mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-29 22:00:15 +01:00
Integrate COLR v1 renderer with cairo-ft-font.c
This commit is contained in:
parent
e892d0e92f
commit
3c8dec60e5
8 changed files with 80 additions and 46 deletions
|
|
@ -320,6 +320,7 @@ if freetype_dep.found()
|
|||
}]
|
||||
|
||||
ft_check_funcs = [
|
||||
'FT_Get_Color_Glyph_Paint',
|
||||
'FT_Get_X11_Font_Format',
|
||||
'FT_GlyphSlot_Embolden',
|
||||
'FT_GlyphSlot_Oblique',
|
||||
|
|
|
|||
|
|
@ -29,23 +29,24 @@
|
|||
* Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <freetype/config/ftoption.h>
|
||||
#include <freetype/ftcolor.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftsizes.h>
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-array-private.h"
|
||||
#include "cairo-ft-private.h"
|
||||
|
||||
#include "cairo-array-private.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_FT_GET_COLOR_GLYPH_PAINT
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_CONFIG_OPTIONS_H
|
||||
#include FT_COLOR_H
|
||||
#include FT_GLYPH_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_SIZES_H
|
||||
|
||||
#ifdef TT_SUPPORT_COLRV1
|
||||
|
||||
/* {{{ Utilities */
|
||||
|
||||
|
|
@ -829,27 +830,6 @@ _cairo_colr_glyph_bounds (FT_Face face,
|
|||
return CAIRO_STATUS_CLIP_NOT_REPRESENTABLE;
|
||||
}
|
||||
|
||||
/* Return what COLR table version this glyph is using, 0 or 1.
|
||||
* Return -1 if the glyph is not in the COLR table.
|
||||
*/
|
||||
int
|
||||
_cairo_colr_glyph_version (FT_Face face,
|
||||
unsigned long glyph)
|
||||
{
|
||||
FT_OpaquePaint paint = { NULL, 0 };
|
||||
FT_UInt glyph_index, color_index;
|
||||
FT_LayerIterator iter;
|
||||
|
||||
if (FT_Get_Color_Glyph_Paint (face, glyph, FT_COLOR_INCLUDE_ROOT_TRANSFORM, &paint))
|
||||
return 1;
|
||||
|
||||
iter.p = NULL;
|
||||
if (FT_Get_Color_Glyph_Layer (face, glyph, &glyph_index, &color_index, &iter))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
colorline_uses_foreground (FT_Face face,
|
||||
FT_ColorLine *colorline)
|
||||
|
|
@ -1575,7 +1555,7 @@ add_sweep_gradient_patches (ColorLine *cl,
|
|||
a0, c0,
|
||||
2 * M_PI, &color,
|
||||
pattern);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1586,7 +1566,6 @@ add_sweep_gradient_patches (ColorLine *cl,
|
|||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2106,6 +2085,6 @@ cleanup:
|
|||
|
||||
/* }}} */
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_FT_GET_COLOR_GLYPH_PAINT */
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
|
|
|||
|
|
@ -2498,6 +2498,7 @@ typedef enum {
|
|||
CAIRO_FT_GLYPH_TYPE_OUTLINE,
|
||||
CAIRO_FT_GLYPH_TYPE_SVG,
|
||||
CAIRO_FT_GLYPH_TYPE_COLR_V0,
|
||||
CAIRO_FT_GLYPH_TYPE_COLR_V1,
|
||||
} cairo_ft_glyph_format_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -2600,6 +2601,7 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
|
|||
cairo_status_t status;
|
||||
cairo_image_surface_t *surface;
|
||||
cairo_bool_t uses_foreground_color = FALSE;
|
||||
cairo_ft_glyph_private_t *glyph_priv = scaled_glyph->dev_private;
|
||||
|
||||
/* Only one info type at a time handled in this function */
|
||||
assert (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE || info == CAIRO_SCALED_GLYPH_INFO_SURFACE);
|
||||
|
|
@ -2643,7 +2645,17 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
|
|||
|
||||
glyph = face->glyph;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
if (glyph_priv->format == CAIRO_FT_GLYPH_TYPE_COLR_V1) {
|
||||
uses_foreground_color = _cairo_colr_glyph_uses_foreground (face,
|
||||
_cairo_scaled_glyph_index(scaled_glyph));
|
||||
status = _cairo_render_colr_glyph (face,
|
||||
glyph->glyph_index,
|
||||
scaled_font->base.options.palette_index,
|
||||
foreground_color,
|
||||
&surface);
|
||||
} else if (glyph_priv->format == CAIRO_FT_GLYPH_TYPE_COLR_V0 ||
|
||||
glyph_priv->format == CAIRO_FT_GLYPH_TYPE_OUTLINE) {
|
||||
|
||||
status = _render_glyph_outline (face, &scaled_font->ft_options.base,
|
||||
&surface);
|
||||
} else {
|
||||
|
|
@ -3084,9 +3096,8 @@ _cairo_ft_scaled_glyph_get_metrics (cairo_ft_scaled_font_t *scaled_font,
|
|||
|
||||
static cairo_bool_t
|
||||
_cairo_ft_scaled_glyph_is_colr_v0 (cairo_ft_scaled_font_t *scaled_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
FT_Face face)
|
||||
|
||||
{
|
||||
#ifdef HAVE_FT_PALETTE_SELECT
|
||||
FT_LayerIterator iterator;
|
||||
|
|
@ -3095,15 +3106,33 @@ _cairo_ft_scaled_glyph_is_colr_v0 (cairo_ft_scaled_font_t *scaled_font,
|
|||
|
||||
iterator.p = NULL;
|
||||
if (FT_Get_Color_Glyph_Layer(face,
|
||||
_cairo_scaled_glyph_index (scaled_glyph),
|
||||
&layer_glyph_index,
|
||||
&layer_color_index,
|
||||
&iterator))
|
||||
_cairo_scaled_glyph_index (scaled_glyph),
|
||||
&layer_glyph_index,
|
||||
&layer_color_index,
|
||||
&iterator) == 1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_ft_scaled_glyph_is_colr_v1 (cairo_ft_scaled_font_t *scaled_font,
|
||||
cairo_scaled_glyph_t *scaled_glyph,
|
||||
FT_Face face)
|
||||
{
|
||||
#if HAVE_FT_GET_COLOR_GLYPH_PAINT
|
||||
FT_OpaquePaint paint = { NULL, 0 };
|
||||
|
||||
if (FT_Get_Color_Glyph_Paint (face,
|
||||
_cairo_scaled_glyph_index (scaled_glyph),
|
||||
FT_COLOR_INCLUDE_ROOT_TRANSFORM,
|
||||
&paint) == 1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -3160,7 +3189,9 @@ _cairo_ft_scaled_glyph_init_metrics (cairo_ft_scaled_font_t *scaled_font,
|
|||
if (is_svg_format) {
|
||||
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_SVG;
|
||||
} else if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
if (_cairo_ft_scaled_glyph_is_colr_v0 (scaled_font, scaled_glyph, face))
|
||||
if (_cairo_ft_scaled_glyph_is_colr_v1 (scaled_font, scaled_glyph, face))
|
||||
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_COLR_V1;
|
||||
else if (_cairo_ft_scaled_glyph_is_colr_v0 (scaled_font, scaled_glyph, face))
|
||||
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_COLR_V0;
|
||||
else
|
||||
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_OUTLINE;
|
||||
|
|
@ -3252,6 +3283,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
|||
switch (glyph_priv->format) {
|
||||
case CAIRO_FT_GLYPH_TYPE_BITMAP:
|
||||
case CAIRO_FT_GLYPH_TYPE_OUTLINE:
|
||||
case CAIRO_FT_GLYPH_TYPE_COLR_V1:
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
break;
|
||||
case CAIRO_FT_GLYPH_TYPE_SVG:
|
||||
|
|
|
|||
|
|
@ -70,6 +70,18 @@ _cairo_render_svg_glyph (const char *svg_document,
|
|||
cairo_t *cr);
|
||||
#endif
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_render_colr_glyph (FT_Face face,
|
||||
unsigned long glyph,
|
||||
FT_UShort palette_index,
|
||||
const cairo_color_t *foreground_color,
|
||||
cairo_image_surface_t **surface);
|
||||
|
||||
cairo_private int
|
||||
_cairo_colr_glyph_uses_foreground (FT_Face face,
|
||||
unsigned long glyph);
|
||||
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_HAS_FT_FONT */
|
||||
|
|
|
|||
|
|
@ -1048,6 +1048,7 @@ cairo_pattern_create_mesh (void)
|
|||
|
||||
return &pattern->base;
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_create_mesh);
|
||||
|
||||
/**
|
||||
* cairo_pattern_reference:
|
||||
|
|
@ -1283,7 +1284,7 @@ cairo_mesh_pattern_begin_patch (cairo_pattern_t *pattern)
|
|||
for (i = 0; i < 4; i++)
|
||||
mesh->has_color[i] = FALSE;
|
||||
}
|
||||
|
||||
slim_hidden_def (cairo_mesh_pattern_begin_patch);
|
||||
|
||||
static void
|
||||
_calc_control_point (cairo_mesh_patch_t *patch, int control_point)
|
||||
|
|
@ -1400,6 +1401,7 @@ cairo_mesh_pattern_end_patch (cairo_pattern_t *pattern)
|
|||
|
||||
mesh->current_patch = NULL;
|
||||
}
|
||||
slim_hidden_def (cairo_mesh_pattern_end_patch);
|
||||
|
||||
/**
|
||||
* cairo_mesh_pattern_curve_to:
|
||||
|
|
|
|||
|
|
@ -1595,6 +1595,7 @@ cairo_identity_matrix (cairo_t *cr)
|
|||
if (unlikely (status))
|
||||
_cairo_set_error (cr, status);
|
||||
}
|
||||
slim_hidden_def (cairo_identity_matrix);
|
||||
|
||||
/**
|
||||
* cairo_user_to_device:
|
||||
|
|
@ -2874,6 +2875,7 @@ cairo_clip_extents (cairo_t *cr,
|
|||
if (unlikely (status))
|
||||
_cairo_set_error (cr, status);
|
||||
}
|
||||
slim_hidden_def (cairo_clip_extents);
|
||||
|
||||
/**
|
||||
* cairo_in_clip:
|
||||
|
|
|
|||
|
|
@ -1950,6 +1950,7 @@ slim_hidden_proto (cairo_append_path);
|
|||
slim_hidden_proto (cairo_arc);
|
||||
slim_hidden_proto (cairo_arc_negative);
|
||||
slim_hidden_proto (cairo_clip);
|
||||
slim_hidden_proto (cairo_clip_extents);
|
||||
slim_hidden_proto (cairo_clip_preserve);
|
||||
slim_hidden_proto (cairo_close_path);
|
||||
slim_hidden_proto (cairo_copy_path);
|
||||
|
|
@ -1983,6 +1984,7 @@ slim_hidden_proto (cairo_get_tolerance);
|
|||
slim_hidden_proto (cairo_glyph_allocate);
|
||||
slim_hidden_proto (cairo_glyph_free);
|
||||
slim_hidden_proto (cairo_has_current_point);
|
||||
slim_hidden_proto (cairo_identity_matrix);
|
||||
slim_hidden_proto (cairo_image_surface_create);
|
||||
slim_hidden_proto (cairo_image_surface_create_for_data);
|
||||
slim_hidden_proto (cairo_image_surface_get_data);
|
||||
|
|
@ -2004,7 +2006,9 @@ slim_hidden_proto (cairo_matrix_scale);
|
|||
slim_hidden_proto (cairo_matrix_transform_distance);
|
||||
slim_hidden_proto (cairo_matrix_transform_point);
|
||||
slim_hidden_proto (cairo_matrix_translate);
|
||||
slim_hidden_proto (cairo_mesh_pattern_begin_patch);
|
||||
slim_hidden_proto (cairo_mesh_pattern_curve_to);
|
||||
slim_hidden_proto (cairo_mesh_pattern_end_patch);
|
||||
slim_hidden_proto (cairo_mesh_pattern_get_control_point);
|
||||
slim_hidden_proto (cairo_mesh_pattern_get_corner_color_rgba);
|
||||
slim_hidden_proto (cairo_mesh_pattern_get_patch_count);
|
||||
|
|
@ -2020,6 +2024,7 @@ slim_hidden_proto_no_warn (cairo_path_destroy);
|
|||
slim_hidden_proto (cairo_pattern_add_color_stop_rgba);
|
||||
slim_hidden_proto (cairo_pattern_create_for_surface);
|
||||
slim_hidden_proto (cairo_pattern_create_linear);
|
||||
slim_hidden_proto (cairo_pattern_create_mesh);
|
||||
slim_hidden_proto (cairo_pattern_create_radial);
|
||||
slim_hidden_proto (cairo_pattern_create_rgb);
|
||||
slim_hidden_proto (cairo_pattern_create_rgba);
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ cairo_feature_sources = {
|
|||
],
|
||||
'cairo-ft': [
|
||||
'cairo-ft-font.c',
|
||||
'cairo-colr-glyph-render.c',
|
||||
'cairo-svg-glyph-render.c'
|
||||
],
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue