[hb-cairo] Add hb_cairo_context_t

This commit is contained in:
Behdad Esfahbod 2023-01-23 15:44:22 -07:00
parent 279f13c187
commit b684c6edd4
3 changed files with 60 additions and 34 deletions

View File

@ -91,7 +91,7 @@ _hb_cairo_destroy_blob (void *p)
} }
hb_bool_t hb_bool_t
_hb_cairo_paint_glyph_image (cairo_t *cr, _hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
hb_blob_t *blob, hb_blob_t *blob,
unsigned width, unsigned width,
unsigned height, unsigned height,
@ -99,6 +99,8 @@ _hb_cairo_paint_glyph_image (cairo_t *cr,
float slant, float slant,
hb_glyph_extents_t *extents) hb_glyph_extents_t *extents)
{ {
cairo_t *cr = c->cr;
if (!extents) /* SVG currently. */ if (!extents) /* SVG currently. */
return false; return false;
@ -273,12 +275,14 @@ _hb_cairo_normalize_color_line (hb_color_stop_t *stops,
} }
void void
_hb_cairo_paint_linear_gradient (cairo_t *cr, _hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line, hb_color_line_t *color_line,
float x0, float y0, float x0, float y0,
float x1, float y1, float x1, float y1,
float x2, float y2) float x2, float y2)
{ {
cairo_t *cr = c->cr;
hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
hb_color_stop_t *stops = stops_; hb_color_stop_t *stops = stops_;
unsigned int len; unsigned int len;
@ -322,11 +326,13 @@ _hb_cairo_paint_linear_gradient (cairo_t *cr,
} }
void void
_hb_cairo_paint_radial_gradient (cairo_t *cr, _hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line, hb_color_line_t *color_line,
float x0, float y0, float r0, float x0, float y0, float r0,
float x1, float y1, float r1) float x1, float y1, float r1)
{ {
cairo_t *cr = c->cr;
hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
hb_color_stop_t *stops = stops_; hb_color_stop_t *stops = stops_;
unsigned int len; unsigned int len;
@ -790,12 +796,14 @@ done:
} }
void void
_hb_cairo_paint_sweep_gradient (cairo_t *cr, _hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line, hb_color_line_t *color_line,
float cx, float cy, float cx, float cy,
float start_angle, float start_angle,
float end_angle) float end_angle)
{ {
cairo_t *cr = c->cr;
unsigned int len; unsigned int len;
hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
hb_color_stop_t *stops = stops_; hb_color_stop_t *stops = stops_;

View File

@ -31,6 +31,13 @@
#include "hb-cairo.h" #include "hb-cairo.h"
typedef struct
{
cairo_scaled_font_t *scaled_font;
cairo_t *cr;
hb_map_t *color_cache;
} hb_cairo_context_t;
static inline cairo_operator_t static inline cairo_operator_t
_hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) _hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
{ {
@ -69,7 +76,7 @@ _hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
} }
HB_INTERNAL hb_bool_t HB_INTERNAL hb_bool_t
_hb_cairo_paint_glyph_image (cairo_t *cr, _hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
hb_blob_t *blob, hb_blob_t *blob,
unsigned width, unsigned width,
unsigned height, unsigned height,
@ -78,20 +85,20 @@ _hb_cairo_paint_glyph_image (cairo_t *cr,
hb_glyph_extents_t *extents); hb_glyph_extents_t *extents);
HB_INTERNAL void HB_INTERNAL void
_hb_cairo_paint_linear_gradient (cairo_t *cr, _hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line, hb_color_line_t *color_line,
float x0, float y0, float x0, float y0,
float x1, float y1, float x1, float y1,
float x2, float y2); float x2, float y2);
HB_INTERNAL void HB_INTERNAL void
_hb_cairo_paint_radial_gradient (cairo_t *cr, _hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line, hb_color_line_t *color_line,
float x0, float y0, float r0, float x0, float y0, float r0,
float x1, float y1, float r1); float x1, float y1, float r1);
HB_INTERNAL void HB_INTERNAL void
_hb_cairo_paint_sweep_gradient (cairo_t *cr, _hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
hb_color_line_t *color_line, hb_color_line_t *color_line,
float x0, float y0, float x0, float y0,
float start_angle, float end_angle); float start_angle, float end_angle);

View File

@ -146,7 +146,9 @@ hb_cairo_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
float dx, float dy, float dx, float dy,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_matrix_t m; cairo_matrix_t m;
cairo_save (cr); cairo_save (cr);
@ -161,7 +163,8 @@ hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data, void *paint_data,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_restore (cr); cairo_restore (cr);
} }
@ -173,7 +176,8 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_font_t *font, hb_font_t *font,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_save (cr); cairo_save (cr);
cairo_new_path (cr); cairo_new_path (cr);
@ -188,7 +192,8 @@ hb_cairo_push_clip_rectangle (hb_paint_funcs_t *pfuncs HB_UNUSED,
float xmin, float ymin, float xmax, float ymax, float xmin, float ymin, float xmax, float ymax,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_save (cr); cairo_save (cr);
cairo_rectangle (cr, cairo_rectangle (cr,
@ -202,7 +207,8 @@ hb_cairo_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data, void *paint_data,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_restore (cr); cairo_restore (cr);
} }
@ -212,7 +218,8 @@ hb_cairo_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
void *paint_data, void *paint_data,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_save (cr); cairo_save (cr);
cairo_push_group (cr); cairo_push_group (cr);
@ -224,7 +231,8 @@ hb_cairo_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_paint_composite_mode_t mode, hb_paint_composite_mode_t mode,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_pop_group_to_source (cr); cairo_pop_group_to_source (cr);
cairo_set_operator (cr, _hb_paint_composite_mode_to_cairo (mode)); cairo_set_operator (cr, _hb_paint_composite_mode_to_cairo (mode));
@ -240,7 +248,8 @@ hb_cairo_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_color_t color, hb_color_t color,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
cairo_set_source_rgba (cr, cairo_set_source_rgba (cr,
hb_color_get_red (color) / 255., hb_color_get_red (color) / 255.,
@ -261,9 +270,9 @@ hb_cairo_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_glyph_extents_t *extents, hb_glyph_extents_t *extents,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
return _hb_cairo_paint_glyph_image (cr, blob, width, height, format, slant, extents); return _hb_cairo_paint_glyph_image (c, blob, width, height, format, slant, extents);
} }
static void static void
@ -275,9 +284,9 @@ hb_cairo_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float x2, float y2, float x2, float y2,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *)paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
_hb_cairo_paint_linear_gradient (cr, color_line, x0, y0, x1, y1, x2, y2); _hb_cairo_paint_linear_gradient (c, color_line, x0, y0, x1, y1, x2, y2);
} }
static void static void
@ -288,9 +297,9 @@ hb_cairo_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float x1, float y1, float r1, float x1, float y1, float r1,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *)paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
_hb_cairo_paint_radial_gradient (cr, color_line, x0, y0, r0, x1, y1, r1); _hb_cairo_paint_radial_gradient (c, color_line, x0, y0, r0, x1, y1, r1);
} }
static void static void
@ -301,9 +310,9 @@ hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
float start_angle, float end_angle, float start_angle, float end_angle,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
_hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle); _hb_cairo_paint_sweep_gradient (c, color_line, x0, y0, start_angle, end_angle);
} }
static const cairo_user_data_key_t color_cache_key = {0}; static const cairo_user_data_key_t color_cache_key = {0};
@ -322,17 +331,18 @@ hb_cairo_paint_custom_palette_color (hb_paint_funcs_t *funcs,
void *user_data HB_UNUSED) void *user_data HB_UNUSED)
{ {
#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR #ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
cairo_t *cr = (cairo_t *) paint_data; hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
cairo_t *cr = c->cr;
#define HB_DEADBEEF HB_TAG(0xDE,0xAD,0xBE,0xEF) #define HB_DEADBEEF HB_TAG(0xDE,0xAD,0xBE,0xEF)
hb_map_t *color_cache = (hb_map_t *) cairo_get_user_data (cr, &color_cache_key); hb_map_t *color_cache = c->color_cache;
hb_codepoint_t *c; hb_codepoint_t *v;
if (likely (color_cache && color_cache->has (color_index, &c))) if (likely (color_cache && color_cache->has (color_index, &v)))
{ {
if (*c == HB_DEADBEEF) if (*v == HB_DEADBEEF)
return false; return false;
*color = *c; *color = *v;
return true; return true;
} }
@ -585,12 +595,13 @@ hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font,
hb_font_get_scale (font, &x_scale, &y_scale); hb_font_get_scale (font, &x_scale, &y_scale);
cairo_scale (cr, +1./x_scale, -1./y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale);
void *color_cache = cairo_scaled_font_get_user_data (scaled_font, &color_cache_key); hb_cairo_context_t c;
cairo_set_user_data (cr, &color_cache_key, color_cache, nullptr); c.scaled_font = scaled_font;
c.cr = cr;
c.color_cache = (hb_map_t *) cairo_scaled_font_get_user_data (scaled_font, &color_cache_key);
hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), cr, palette, color); hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color);
cairo_set_user_data (cr, &color_cache_key, nullptr, nullptr);
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }