diff --git a/configure.ac b/configure.ac index 0ca0c8e2b..8ff3f35d6 100644 --- a/configure.ac +++ b/configure.ac @@ -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([ diff --git a/meson.build b/meson.build index 7a0506712..6236d743b 100644 --- a/meson.build +++ b/meson.build @@ -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' diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index adfb445df..66300dd03 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -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)) diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c index 5923af441..0384dbf24 100644 --- a/src/cairo-gl-glyphs.c +++ b/src/cairo-gl-glyphs.c @@ -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; diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 0ded5388e..0a293f05d 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -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)) diff --git a/src/cairo-quartz-font.c b/src/cairo-quartz-font.c index 8cb71434f..77a9d6a55 100644 --- a/src/cairo-quartz-font.c +++ b/src/cairo-quartz-font.c @@ -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; diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h index 4bacb1a01..42e9b0913 100644 --- a/src/cairo-scaled-font-private.h +++ b/src/cairo-scaled-font-private.h @@ -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 { diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index 0ae41aebe..94a7aae26 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -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); } diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 65c1d2595..ef0db0506 100755 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -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; diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c index 9d6b954c1..ca9bafbb7 100644 --- a/src/cairo-script-surface.c +++ b/src/cairo-script-surface.c @@ -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); diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 380759db9..eea7d6030 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -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; diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index 80f3a0eb0..c6d9382b3 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -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; diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c index 0b8e66cd0..3a44c4666 100644 --- a/src/cairo-type1-fallback.c +++ b/src/cairo-type1-fallback.c @@ -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)) diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 6b2102319..05ef417dc 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -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; diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c index 04c9ee699..47b9f0422 100644 --- a/src/cairo-user-font.c +++ b/src/cairo-user-font.c @@ -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); } } diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index a1eaad9a5..5993aa378 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -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); diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c index bf8d20546..c872f5680 100644 --- a/src/cairo-xlib-render-compositor.c +++ b/src/cairo-xlib-render-compositor.c @@ -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; diff --git a/src/cairoint.h b/src/cairoint.h index 1e0cb4bf1..c5872b8cc 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -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 diff --git a/src/drm/cairo-drm-i915-glyphs.c b/src/drm/cairo-drm-i915-glyphs.c index 3b0efc248..6fdcc0d2b 100644 --- a/src/drm/cairo-drm-i915-glyphs.c +++ b/src/drm/cairo-drm-i915-glyphs.c @@ -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; diff --git a/src/drm/cairo-drm-i965-glyphs.c b/src/drm/cairo-drm-i965-glyphs.c index 1ef0a6f59..22ace66e3 100644 --- a/src/drm/cairo-drm-i965-glyphs.c +++ b/src/drm/cairo-drm-i965-glyphs.c @@ -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; diff --git a/src/drm/cairo-drm-intel.c b/src/drm/cairo-drm-intel.c index e45f999ec..ce6c38040 100644 --- a/src/drm/cairo-drm-intel.c +++ b/src/drm/cairo-drm-intel.c @@ -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; diff --git a/src/test-base-compositor-surface.c b/src/test-base-compositor-surface.c index ff84b10af..00e3d0c56 100644 --- a/src/test-base-compositor-surface.c +++ b/src/test-base-compositor-surface.c @@ -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)) diff --git a/src/win32/cairo-win32-font.c b/src/win32/cairo-win32-font.c index 792e329d4..eb4ba7a22 100644 --- a/src/win32/cairo-win32-font.c +++ b/src/win32/cairo-win32-font.c @@ -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; diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c index 36d17e960..19b7f9e93 100644 --- a/src/win32/cairo-win32-printing-surface.c +++ b/src/win32/cairo-win32-printing-surface.c @@ -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;