mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-04 10:40:58 +01:00
Support color fonts that use the foreground color
COLR fonts can have a layer with the same color as the current text color. This change passes the current color (if solid) through to the font backend where it can be used to render color fonts. scaled_glyph_lookup checks if the foreground color has changed (for glyph that require it) and requests a new color surface if required. This also fixes a bug where scaled_glyph_lookup would always request a color surface for glyphs for glyphs in color fonts that do not have color.
This commit is contained in:
parent
5e76dd7a5c
commit
fea2463107
24 changed files with 160 additions and 17 deletions
|
|
@ -561,7 +561,7 @@ if test "x$use_ft" = "xyes"; then
|
|||
LIBS="$LIBS $ft_LIBS"
|
||||
CFLAGS="$CFLAGS $ft_CFLAGS"
|
||||
|
||||
AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var)
|
||||
AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var FT_Palette_Set_Foreground_Color)
|
||||
|
||||
AC_MSG_CHECKING(for FT_HAS_COLOR)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
||||
|
|
|
|||
|
|
@ -330,6 +330,7 @@ if freetype_dep.found()
|
|||
'FT_Library_SetLcdFilter',
|
||||
'FT_Get_Var_Design_Coordinates',
|
||||
'FT_Done_MM_Var',
|
||||
'FT_Palette_Set_Foreground_Color',
|
||||
]
|
||||
|
||||
if freetype_dep.type_name() == 'internal'
|
||||
|
|
|
|||
|
|
@ -2479,6 +2479,7 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
|
|||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info,
|
||||
FT_Face face,
|
||||
const cairo_color_t *foreground_color,
|
||||
cairo_bool_t vertical_layout,
|
||||
int load_flags)
|
||||
{
|
||||
|
|
@ -2486,11 +2487,40 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
|
|||
FT_GlyphSlot glyph;
|
||||
cairo_status_t status;
|
||||
cairo_image_surface_t *surface;
|
||||
cairo_bool_t uses_foreground_color = FALSE;
|
||||
|
||||
if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
|
||||
if (!unscaled->have_color)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
#ifdef HAVE_FT_PALETTE_SET_FOREGROUND_COLOR
|
||||
FT_LayerIterator iterator;
|
||||
FT_UInt layer_glyph_index;
|
||||
FT_UInt layer_color_index;
|
||||
FT_Color color;
|
||||
|
||||
/* Check if there is a layer that uses the foreground color */
|
||||
iterator.p = NULL;
|
||||
while (FT_Get_Color_Glyph_Layer(face,
|
||||
_cairo_scaled_glyph_index(scaled_glyph),
|
||||
&layer_glyph_index,
|
||||
&layer_color_index,
|
||||
&iterator)) {
|
||||
if (layer_color_index == 0xFFFF) {
|
||||
uses_foreground_color = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uses_foreground_color) {
|
||||
color.red = (FT_Byte)(foreground_color->red * 0xFF);
|
||||
color.green = (FT_Byte)(foreground_color->green * 0xFF);
|
||||
color.blue = (FT_Byte)(foreground_color->blue * 0xFF);
|
||||
color.alpha = (FT_Byte)(foreground_color->alpha * 0xFF);
|
||||
FT_Palette_Set_Foreground_Color (face, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
load_flags &= ~FT_LOAD_MONOCHROME;
|
||||
/* clear load target mode */
|
||||
load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(load_flags)));
|
||||
|
|
@ -2534,11 +2564,14 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
|
|||
!pixman_image_get_component_alpha (surface->pixman_image)) {
|
||||
_cairo_scaled_glyph_set_color_surface (scaled_glyph,
|
||||
&scaled_font->base,
|
||||
surface);
|
||||
surface,
|
||||
uses_foreground_color);
|
||||
} else {
|
||||
_cairo_scaled_glyph_set_surface (scaled_glyph,
|
||||
&scaled_font->base,
|
||||
surface);
|
||||
if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)
|
||||
scaled_glyph->not_color_glyph = TRUE;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
@ -2547,7 +2580,8 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
|
|||
static cairo_int_status_t
|
||||
_cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info)
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color)
|
||||
{
|
||||
cairo_text_extents_t fs_metrics;
|
||||
cairo_ft_scaled_font_t *scaled_font = abstract_font;
|
||||
|
|
@ -2698,6 +2732,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
scaled_glyph,
|
||||
CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE,
|
||||
face,
|
||||
foreground_color,
|
||||
vertical_layout,
|
||||
load_flags);
|
||||
if (unlikely (status))
|
||||
|
|
@ -2709,6 +2744,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
scaled_glyph,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
face,
|
||||
NULL, /* foreground color */
|
||||
vertical_layout,
|
||||
load_flags);
|
||||
if (unlikely (status))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* Cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Chris Wilson
|
||||
|
|
@ -269,6 +270,7 @@ render_glyphs (cairo_gl_surface_t *dst,
|
|||
status = _cairo_scaled_glyph_lookup (info->font,
|
||||
info->glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto FINISH;
|
||||
|
|
|
|||
|
|
@ -909,6 +909,7 @@ composite_glyphs (void *_dst,
|
|||
CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
|
||||
status = _cairo_scaled_glyph_lookup (info->font, index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
|
||||
|
||||
|
|
@ -997,6 +998,7 @@ composite_one_glyph (void *_dst,
|
|||
status = _cairo_scaled_glyph_lookup (info->font,
|
||||
info->glyphs[0].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
if (unlikely (status))
|
||||
|
|
@ -1059,6 +1061,7 @@ composite_glyphs_via_mask (void *_dst,
|
|||
status = _cairo_scaled_glyph_lookup (info->font,
|
||||
info->glyphs[0].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status)) {
|
||||
pixman_image_unref (white);
|
||||
|
|
@ -1105,6 +1108,7 @@ composite_glyphs_via_mask (void *_dst,
|
|||
{
|
||||
status = _cairo_scaled_glyph_lookup (info->font, glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
if (unlikely (status)) {
|
||||
|
|
@ -1231,6 +1235,7 @@ composite_glyphs (void *_dst,
|
|||
{
|
||||
status = _cairo_scaled_glyph_lookup (info->font, glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
if (unlikely (status))
|
||||
|
|
|
|||
|
|
@ -743,7 +743,8 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
|
|||
static cairo_int_status_t
|
||||
_cairo_quartz_scaled_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info)
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color)
|
||||
{
|
||||
cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font;
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -147,7 +147,14 @@ struct _cairo_scaled_glyph {
|
|||
void *dev_private;
|
||||
cairo_list_t dev_privates;
|
||||
|
||||
cairo_bool_t has_color;
|
||||
cairo_color_t foreground_color; /* only used for color glyphs */
|
||||
/* TRUE if the color_surface used the foreground_color to render. */
|
||||
unsigned uses_foreground_color : 1;
|
||||
|
||||
/* TRUE if this is not a color glyph, FALSE if is a color glyph or unknown. */
|
||||
unsigned not_color_glyph : 1;
|
||||
|
||||
unsigned has_color : 1;
|
||||
};
|
||||
|
||||
struct _cairo_scaled_glyph_private {
|
||||
|
|
|
|||
|
|
@ -513,6 +513,7 @@ _cairo_sub_font_add_glyph (cairo_sub_font_t *sub_font,
|
|||
status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
|
||||
scaled_font_glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
|
||||
if (unlikely (status)) {
|
||||
|
|
@ -890,6 +891,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
scaled_font_glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1611,6 +1611,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status)) {
|
||||
status = _cairo_scaled_font_set_error (scaled_font, status);
|
||||
|
|
@ -1732,6 +1733,7 @@ cairo_scaled_font_text_to_glyphs_internal_cached (cairo_scaled_font_t *scaled_
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
g,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
|
@ -1792,6 +1794,7 @@ cairo_scaled_font_text_to_glyphs_internal_uncached (cairo_scaled_font_t *scaled
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
g,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
|
@ -2176,6 +2179,7 @@ _cairo_scaled_font_single_glyph_device_extents (cairo_scaled_font_t *scaled_fon
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyph->index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (likely (status == CAIRO_STATUS_SUCCESS)) {
|
||||
cairo_bool_t round_xy = _cairo_font_options_get_round_glyph_positions (&scaled_font->options) == CAIRO_ROUND_GLYPH_POS_ON;
|
||||
|
|
@ -2246,6 +2250,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
break;
|
||||
|
|
@ -2402,6 +2407,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
if (unlikely (status))
|
||||
|
|
@ -2656,6 +2662,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (status == CAIRO_INT_STATUS_SUCCESS) {
|
||||
status = _cairo_path_fixed_append (path,
|
||||
|
|
@ -2670,6 +2677,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
|
@ -2830,7 +2838,8 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
|
|||
void
|
||||
_cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
cairo_image_surface_t *surface)
|
||||
cairo_image_surface_t *surface,
|
||||
cairo_bool_t uses_foreground_color)
|
||||
{
|
||||
if (scaled_glyph->color_surface != NULL)
|
||||
cairo_surface_destroy (&scaled_glyph->color_surface->base);
|
||||
|
|
@ -2838,6 +2847,7 @@ _cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
|
|||
/* sanity check the backend glyph contents */
|
||||
_cairo_debug_check_image_surface_is_defined (&surface->base);
|
||||
scaled_glyph->color_surface = surface;
|
||||
scaled_glyph->uses_foreground_color = uses_foreground_color;
|
||||
|
||||
if (surface != NULL)
|
||||
scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
|
||||
|
|
@ -2956,6 +2966,8 @@ _cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font,
|
|||
* @index: the glyph to create
|
||||
* @info: a #cairo_scaled_glyph_info_t marking which portions of
|
||||
* the glyph should be filled in.
|
||||
* @foreground_color - foreground color to use when rendering color fonts. Use NULL
|
||||
* if not requesting CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE or foreground color is unknown.
|
||||
* @scaled_glyph_ret: a #cairo_scaled_glyph_t where the glyph
|
||||
* is returned.
|
||||
*
|
||||
|
|
@ -2976,11 +2988,14 @@ _cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font,
|
|||
* %CAIRO_SCALED_GLYPH_INFO_METRICS - glyph metrics and bounding box
|
||||
* %CAIRO_SCALED_GLYPH_INFO_SURFACE - surface holding glyph image
|
||||
* %CAIRO_SCALED_GLYPH_INFO_PATH - path holding glyph outline in device space
|
||||
* %CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE - surface holding recording of glyph
|
||||
* %CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE - surface holding color glyph image
|
||||
**/
|
||||
cairo_int_status_t
|
||||
_cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
||||
unsigned long index,
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color,
|
||||
cairo_scaled_glyph_t **scaled_glyph_ret)
|
||||
{
|
||||
cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
|
||||
|
|
@ -2998,6 +3013,9 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (foreground_color == NULL)
|
||||
foreground_color = CAIRO_COLOR_BLACK;
|
||||
|
||||
/*
|
||||
* Check cache for glyph
|
||||
*/
|
||||
|
|
@ -3016,7 +3034,8 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
status =
|
||||
scaled_font->backend->scaled_glyph_init (scaled_font,
|
||||
scaled_glyph,
|
||||
info | CAIRO_SCALED_GLYPH_INFO_METRICS);
|
||||
info | CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
foreground_color);
|
||||
if (unlikely (status)) {
|
||||
_cairo_scaled_font_free_last_glyph (scaled_font, scaled_glyph);
|
||||
goto err;
|
||||
|
|
@ -3035,10 +3054,26 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
* already has the requested data and amend it if not
|
||||
*/
|
||||
need_info = info & ~scaled_glyph->has_info;
|
||||
|
||||
/* If this is not a color glyph, don't try loading the color surface again. */
|
||||
if ((need_info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) && scaled_glyph->not_color_glyph)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* If requesting a color surface for a glyph that has used the
|
||||
* foreground color to render the color_surface, and the
|
||||
* foreground color has changed, request a new image. */
|
||||
if ((info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) &&
|
||||
scaled_glyph->uses_foreground_color &&
|
||||
!_cairo_color_equal (foreground_color, &scaled_glyph->foreground_color))
|
||||
{
|
||||
need_info |= CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
|
||||
}
|
||||
|
||||
if (need_info) {
|
||||
status = scaled_font->backend->scaled_glyph_init (scaled_font,
|
||||
scaled_glyph,
|
||||
need_info);
|
||||
need_info,
|
||||
foreground_color);
|
||||
if (unlikely (status))
|
||||
goto err;
|
||||
|
||||
|
|
|
|||
|
|
@ -3194,6 +3194,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[n].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
break;
|
||||
|
|
@ -3204,6 +3205,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[n].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (_cairo_status_is_error (status))
|
||||
break;
|
||||
|
|
@ -3229,6 +3231,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[n].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (_cairo_status_is_error (status))
|
||||
break;
|
||||
|
|
@ -3411,6 +3414,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[n].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status)) {
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
|
|
@ -3434,6 +3438,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[n].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status)) {
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
|
|
|
|||
|
|
@ -2602,6 +2602,7 @@ slim_hidden_def (cairo_surface_has_show_text_glyphs);
|
|||
|
||||
static inline cairo_int_status_t
|
||||
ensure_scaled_glyph (cairo_scaled_font_t *scaled_font,
|
||||
cairo_color_t *foreground_color,
|
||||
cairo_scaled_glyph_t **glyph_cache,
|
||||
cairo_glyph_t *glyph,
|
||||
cairo_scaled_glyph_t **scaled_glyph)
|
||||
|
|
@ -2615,12 +2616,14 @@ ensure_scaled_glyph (cairo_scaled_font_t *scaled_font,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyph->index,
|
||||
CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE,
|
||||
foreground_color,
|
||||
scaled_glyph);
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
/* If the color surface not available, ensure scaled_glyph is not NULL. */
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyph->index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
scaled_glyph);
|
||||
}
|
||||
if (unlikely (status))
|
||||
|
|
@ -2693,6 +2696,10 @@ composite_color_glyphs (cairo_surface_t *surface,
|
|||
int byte_pos = 0;
|
||||
int gp;
|
||||
cairo_scaled_glyph_t *glyph_cache[GLYPH_CACHE_SIZE];
|
||||
cairo_color_t *foreground_color = NULL;
|
||||
|
||||
if (source->type == CAIRO_PATTERN_TYPE_SOLID)
|
||||
foreground_color = &((cairo_solid_pattern_t *) source)->color;
|
||||
|
||||
memset (glyph_cache, 0, sizeof (glyph_cache));
|
||||
|
||||
|
|
@ -2714,7 +2721,7 @@ composite_color_glyphs (cairo_surface_t *surface,
|
|||
else
|
||||
gp = glyph_pos + j;
|
||||
|
||||
status = ensure_scaled_glyph (scaled_font, glyph_cache,
|
||||
status = ensure_scaled_glyph (scaled_font, foreground_color, glyph_cache,
|
||||
&glyphs[gp], &scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto UNLOCK;
|
||||
|
|
@ -2745,7 +2752,7 @@ composite_color_glyphs (cairo_surface_t *surface,
|
|||
else
|
||||
gp = glyph_pos + j;
|
||||
|
||||
status = ensure_scaled_glyph (scaled_font, glyph_cache,
|
||||
status = ensure_scaled_glyph (scaled_font, foreground_color, glyph_cache,
|
||||
&glyphs[gp], &scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto UNLOCK;
|
||||
|
|
@ -2774,7 +2781,7 @@ composite_color_glyphs (cairo_surface_t *surface,
|
|||
} else {
|
||||
|
||||
for (glyph_pos = 0; glyph_pos < *num_glyphs; glyph_pos++) {
|
||||
status = ensure_scaled_glyph (scaled_font, glyph_cache,
|
||||
status = ensure_scaled_glyph (scaled_font, foreground_color, glyph_cache,
|
||||
&glyphs[glyph_pos], &scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto UNLOCK;
|
||||
|
|
|
|||
|
|
@ -1326,6 +1326,7 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
|
|
@ -1357,6 +1358,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status)) {
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
|
|
@ -354,6 +355,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
|||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS|
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
/* It is ok for the .notdef glyph to not have a path available. We
|
||||
|
|
@ -363,6 +365,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font,
|
|||
status = _cairo_scaled_glyph_lookup (font->type1_scaled_font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
}
|
||||
if (unlikely (status))
|
||||
|
|
|
|||
|
|
@ -373,6 +373,7 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
|
|||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS |
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
|
@ -428,6 +429,7 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
|
|||
status = _cairo_scaled_glyph_lookup (surface->scaled_font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
if (_cairo_int_status_is_error (status))
|
||||
|
|
@ -480,11 +482,13 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
|
|||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS |
|
||||
CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
status = _cairo_scaled_glyph_lookup (surface->scaled_font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (status == CAIRO_INT_STATUS_SUCCESS)
|
||||
status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ _cairo_user_scaled_font_create_recording_context (const cairo_user_scaled_font_t
|
|||
static cairo_int_status_t
|
||||
_cairo_user_scaled_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info)
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color)
|
||||
{
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_user_scaled_font_t *scaled_font = abstract_font;
|
||||
|
|
@ -300,7 +301,8 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
|
|||
if (scaled_glyph->has_color && (info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) {
|
||||
_cairo_scaled_glyph_set_color_surface (scaled_glyph,
|
||||
&scaled_font->base,
|
||||
(cairo_image_surface_t *)surface);
|
||||
(cairo_image_surface_t *)surface,
|
||||
FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3994,6 +3994,7 @@ _can_composite_glyphs (cairo_xcb_surface_t *dst,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs->index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&glyph);
|
||||
if (unlikely (status))
|
||||
break;
|
||||
|
|
@ -4399,6 +4400,7 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection,
|
|||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS |
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
scaled_glyph_out);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
|
@ -4692,6 +4694,7 @@ _composite_glyphs (void *closure,
|
|||
status = _cairo_scaled_glyph_lookup (info->font,
|
||||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&glyph);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (&src->base);
|
||||
|
|
|
|||
|
|
@ -1204,6 +1204,7 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
|
|||
glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS |
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
pscaled_glyph);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
|
@ -1619,6 +1620,7 @@ composite_glyphs (void *surface,
|
|||
status = _cairo_scaled_glyph_lookup (info->font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&glyph);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -519,10 +519,24 @@ struct _cairo_scaled_font_backend {
|
|||
void
|
||||
(*fini) (void *scaled_font);
|
||||
|
||||
/**
|
||||
* Get the requested glyph info.
|
||||
* @scaled_font: a #cairo_scaled_font_t
|
||||
* @scaled_glyph: a #cairo_scaled_glyph_t the glyph
|
||||
* @info: a #cairo_scaled_glyph_info_t which information to retreive
|
||||
* %CAIRO_SCALED_GLYPH_INFO_METRICS - glyph metrics and bounding box
|
||||
* %CAIRO_SCALED_GLYPH_INFO_SURFACE - surface holding glyph image
|
||||
* %CAIRO_SCALED_GLYPH_INFO_PATH - path holding glyph outline in device space
|
||||
* %CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE - surface holding recording of glyph
|
||||
* %CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE - surface holding color glyph image
|
||||
* @foreground_color - foreground color to use when rendering color fonts. Use NULL
|
||||
* if not requesting CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE or foreground color is unknown.
|
||||
*/
|
||||
cairo_warn cairo_int_status_t
|
||||
(*scaled_glyph_init) (void *scaled_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info);
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color);
|
||||
|
||||
/* A backend only needs to implement this or ucs4_to_index(), not
|
||||
* both. This allows the backend to do something more sophisticated
|
||||
|
|
@ -1284,12 +1298,14 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
|
|||
cairo_private void
|
||||
_cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
cairo_image_surface_t *surface);
|
||||
cairo_image_surface_t *surface,
|
||||
cairo_bool_t uses_foreground_color);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
||||
unsigned long index,
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color,
|
||||
cairo_scaled_glyph_t **scaled_glyph_ret);
|
||||
|
||||
cairo_private double
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
|
|
@ -447,6 +448,7 @@ i915_surface_glyphs (void *abstract_surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto FINISH;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
|
|
@ -366,6 +367,7 @@ i965_surface_glyphs (void *abstract_surface,
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
g[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
goto FINISH;
|
||||
|
|
|
|||
|
|
@ -994,7 +994,8 @@ intel_get_glyph (intel_device_t *device,
|
|||
status =
|
||||
scaled_font->backend->scaled_glyph_init (scaled_font,
|
||||
scaled_glyph,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE);
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
|
|
|
|||
|
|
@ -734,6 +734,7 @@ composite_glyphs (cairo_image_surface_t *dst,
|
|||
|
||||
status = _cairo_scaled_glyph_lookup (info->font, glyph_index,
|
||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
|
||||
if (unlikely (status))
|
||||
|
|
|
|||
|
|
@ -715,6 +715,7 @@ _cairo_win32_scaled_font_type1_text_to_glyphs (cairo_win32_scaled_font_t *scaled
|
|||
status = _cairo_scaled_glyph_lookup (&scaled_font->base,
|
||||
glyph_indices[i],
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (status) {
|
||||
free (*glyphs);
|
||||
|
|
@ -1319,7 +1320,8 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
|
|||
static cairo_int_status_t
|
||||
_cairo_win32_scaled_font_glyph_init (void *abstract_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_info_t info)
|
||||
cairo_scaled_glyph_info_t info,
|
||||
const cairo_color_t *foreground_color)
|
||||
{
|
||||
cairo_win32_scaled_font_t *scaled_font = abstract_font;
|
||||
cairo_status_t status;
|
||||
|
|
|
|||
|
|
@ -1865,6 +1865,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
break;
|
||||
|
|
@ -1919,6 +1920,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
|||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||
NULL, /* foreground color */
|
||||
&scaled_glyph);
|
||||
if (status)
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue