Merge pull request #4045 from harfbuzz/custom-palette-cairo
Custom palette cairo
This commit is contained in:
commit
32f9b467d6
|
@ -225,8 +225,6 @@ hb_draw_state_t
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>hb-paint</FILE>
|
<FILE>hb-paint</FILE>
|
||||||
HB_PAINT_PALETTE_INDEX_CUSTOM
|
|
||||||
|
|
||||||
hb_paint_funcs_t
|
hb_paint_funcs_t
|
||||||
hb_paint_funcs_create
|
hb_paint_funcs_create
|
||||||
hb_paint_funcs_get_empty
|
hb_paint_funcs_get_empty
|
||||||
|
|
|
@ -213,6 +213,7 @@ if cairo_dep.found()
|
||||||
conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
|
conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
|
||||||
else
|
else
|
||||||
check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
|
check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
|
||||||
|
check_funcs += [['cairo_font_options_get_custom_palette_color', {'deps': cairo_dep}]]
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -97,15 +97,13 @@ public:
|
||||||
|
|
||||||
if (color_index != 0xffff)
|
if (color_index != 0xffff)
|
||||||
{
|
{
|
||||||
if (palette_index != HB_PAINT_PALETTE_INDEX_CUSTOM)
|
if (!funcs->custom_palette_color (data, color_index, &color))
|
||||||
{
|
{
|
||||||
unsigned int clen = 1;
|
unsigned int clen = 1;
|
||||||
hb_face_t *face = hb_font_get_face (font);
|
hb_face_t *face = hb_font_get_face (font);
|
||||||
|
|
||||||
hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
|
hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
color = funcs->custom_palette_color (data, color_index);
|
|
||||||
|
|
||||||
*is_foreground = false;
|
*is_foreground = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,6 +306,68 @@ hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
|
||||||
_hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle);
|
_hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const cairo_user_data_key_t color_cache_key = {0};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_hb_cairo_destroy_map (void *p)
|
||||||
|
{
|
||||||
|
hb_map_destroy ((hb_map_t *) p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_cairo_paint_custom_palette_color (hb_paint_funcs_t *funcs,
|
||||||
|
void *paint_data,
|
||||||
|
unsigned int color_index,
|
||||||
|
hb_color_t *color,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
|
||||||
|
cairo_t *cr = (cairo_t *) paint_data;
|
||||||
|
|
||||||
|
#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_codepoint_t *c;
|
||||||
|
if (likely (color_cache && color_cache->has (color_index, &c)))
|
||||||
|
{
|
||||||
|
if (*c == HB_DEADBEEF)
|
||||||
|
return false;
|
||||||
|
*color = *c;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_font_options_t *options;
|
||||||
|
double red, green, blue, alpha;
|
||||||
|
|
||||||
|
options = cairo_font_options_create ();
|
||||||
|
cairo_get_font_options (cr, options);
|
||||||
|
if (CAIRO_STATUS_SUCCESS ==
|
||||||
|
cairo_font_options_get_custom_palette_color (options, color_index,
|
||||||
|
&red, &green, &blue, &alpha))
|
||||||
|
{
|
||||||
|
cairo_font_options_destroy (options);
|
||||||
|
*color = HB_COLOR (round (255 * blue),
|
||||||
|
round (255 * green),
|
||||||
|
round (255 * red),
|
||||||
|
round (255 * alpha));
|
||||||
|
|
||||||
|
if (likely (color_cache && *color != HB_DEADBEEF))
|
||||||
|
color_cache->set (color_index, *color);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cairo_font_options_destroy (options);
|
||||||
|
|
||||||
|
if (likely (color_cache))
|
||||||
|
color_cache->set (color_index, HB_DEADBEEF);
|
||||||
|
|
||||||
|
#undef HB_DEADBEEF
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void free_static_cairo_paint_funcs ();
|
static inline void free_static_cairo_paint_funcs ();
|
||||||
|
|
||||||
static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_cairo_paint_funcs_lazy_loader_t>
|
static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_cairo_paint_funcs_lazy_loader_t>
|
||||||
|
@ -326,6 +388,7 @@ static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<
|
||||||
hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr);
|
hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr);
|
||||||
hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr);
|
hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr);
|
||||||
hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr);
|
hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr);
|
||||||
|
hb_paint_funcs_set_custom_palette_color_func (funcs, hb_cairo_paint_custom_palette_color, nullptr, nullptr);
|
||||||
|
|
||||||
hb_paint_funcs_make_immutable (funcs);
|
hb_paint_funcs_make_immutable (funcs);
|
||||||
|
|
||||||
|
@ -346,12 +409,6 @@ hb_cairo_paint_get_funcs ()
|
||||||
{
|
{
|
||||||
return static_cairo_paint_funcs.get_unconst ();
|
return static_cairo_paint_funcs.get_unconst ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font,
|
|
||||||
unsigned long glyph,
|
|
||||||
cairo_t *cr,
|
|
||||||
cairo_text_extents_t *extents);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const cairo_user_data_key_t hb_cairo_face_user_data_key = {0};
|
static const cairo_user_data_key_t hb_cairo_face_user_data_key = {0};
|
||||||
|
@ -439,6 +496,11 @@ hb_cairo_init_scaled_font (cairo_scaled_font_t *scaled_font,
|
||||||
extents->descent = (double) -hb_extents.descender / y_scale;
|
extents->descent = (double) -hb_extents.descender / y_scale;
|
||||||
extents->height = extents->ascent + extents->descent;
|
extents->height = extents->ascent + extents->descent;
|
||||||
|
|
||||||
|
#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
|
||||||
|
hb_map_t *color_cache = hb_map_create ();
|
||||||
|
cairo_scaled_font_set_user_data (scaled_font, &color_cache_key, color_cache, _hb_cairo_destroy_map);
|
||||||
|
#endif
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,19 +577,21 @@ hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font,
|
||||||
|
|
||||||
hb_color_t color = HB_COLOR (0, 0, 0, 255);
|
hb_color_t color = HB_COLOR (0, 0, 0, 255);
|
||||||
cairo_pattern_t *pattern = cairo_get_source (cr);
|
cairo_pattern_t *pattern = cairo_get_source (cr);
|
||||||
if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
|
double r, g, b, a;
|
||||||
{
|
if (cairo_pattern_get_rgba (pattern, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
|
||||||
double r, g, b, a;
|
color = HB_COLOR (round (b * 255.), round (g * 255.), round (r * 255.), round (a * 255.));
|
||||||
cairo_pattern_get_rgba (pattern, &r, &g, &b, &a);
|
|
||||||
color = HB_COLOR ((int)(b * 255.), (int)(g * 255.), (int) (r * 255.), (int)(a * 255.));
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_position_t x_scale, y_scale;
|
hb_position_t x_scale, y_scale;
|
||||||
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);
|
||||||
|
cairo_set_user_data (cr, &color_cache_key, color_cache, nullptr);
|
||||||
|
|
||||||
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 (), cr, palette, color);
|
||||||
|
|
||||||
|
cairo_set_user_data (cr, &color_cache_key, nullptr, nullptr);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1440,8 +1440,7 @@ hb_font_draw_glyph (hb_font_t *font,
|
||||||
*
|
*
|
||||||
* If the font has color palettes (see hb_ot_color_has_palettes()),
|
* If the font has color palettes (see hb_ot_color_has_palettes()),
|
||||||
* then @palette_index selects the palette to use. If the font only
|
* then @palette_index selects the palette to use. If the font only
|
||||||
* has one palette, this will be 0. Use %HB_PAINT_PALETTE_INDEX_CUSTOM
|
* has one palette, this will be 0.
|
||||||
* for custom palette.
|
|
||||||
*
|
*
|
||||||
* Since: REPLACEME
|
* Since: REPLACEME
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -156,9 +156,9 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line,
|
||||||
(hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
|
(hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (c->palette_index == HB_PAINT_PALETTE_INDEX_CUSTOM)
|
hb_color_t color;
|
||||||
|
if (c->funcs->custom_palette_color (c->data, stop.color.palette_index, &color))
|
||||||
{
|
{
|
||||||
hb_color_t color = c->funcs->custom_palette_color (c->data, stop.color.palette_index);
|
|
||||||
color_stops->color = HB_COLOR (hb_color_get_blue (color),
|
color_stops->color = HB_COLOR (hb_color_get_blue (color),
|
||||||
hb_color_get_green (color),
|
hb_color_get_green (color),
|
||||||
hb_color_get_red (color),
|
hb_color_get_red (color),
|
||||||
|
@ -237,9 +237,8 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
|
||||||
(hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
|
(hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (c->palette_index == HB_PAINT_PALETTE_INDEX_CUSTOM)
|
if (c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index, &color))
|
||||||
{
|
{
|
||||||
color = c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index);
|
|
||||||
color = HB_COLOR (hb_color_get_blue (color),
|
color = HB_COLOR (hb_color_get_blue (color),
|
||||||
hb_color_get_green (color),
|
hb_color_get_green (color),
|
||||||
hb_color_get_red (color),
|
hb_color_get_red (color),
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
#include "hb-machinery.hh"
|
|
||||||
#include "hb-number.hh"
|
#include "hb-number.hh"
|
||||||
#include "hb-number-parser.hh"
|
#include "hb-number-parser.hh"
|
||||||
|
|
||||||
|
|
|
@ -117,10 +117,11 @@ hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data,
|
||||||
hb_paint_composite_mode_t mode,
|
hb_paint_composite_mode_t mode,
|
||||||
void *user_data) {}
|
void *user_data) {}
|
||||||
|
|
||||||
static hb_color_t
|
static hb_bool_t
|
||||||
hb_paint_custom_palette_color_nil (hb_paint_funcs_t *funcs, void *paint_data,
|
hb_paint_custom_palette_color_nil (hb_paint_funcs_t *funcs, void *paint_data,
|
||||||
unsigned int color_index,
|
unsigned int color_index,
|
||||||
void *user_data) { return HB_COLOR(0,0,0,0); }
|
hb_color_t *color,
|
||||||
|
void *user_data) { return false; }
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs,
|
_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs,
|
||||||
|
@ -683,18 +684,20 @@ hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
|
||||||
* @funcs: paint functions
|
* @funcs: paint functions
|
||||||
* @paint_data: associated data passed by the caller
|
* @paint_data: associated data passed by the caller
|
||||||
* @color_index: color index
|
* @color_index: color index
|
||||||
|
* @color: (out): fetched color
|
||||||
*
|
*
|
||||||
* Gets the custom palette color for @color_index.
|
* Gets the custom palette color for @color_index.
|
||||||
*
|
*
|
||||||
* Return value: the custom color
|
* Return value: `true` if found, `false` otherwise
|
||||||
*
|
*
|
||||||
* Since: REPLACEME
|
* Since: REPLACEME
|
||||||
*/
|
*/
|
||||||
hb_color_t
|
hb_bool_t
|
||||||
hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
|
hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
|
||||||
unsigned int color_index)
|
unsigned int color_index,
|
||||||
|
hb_color_t *color)
|
||||||
{
|
{
|
||||||
return funcs->custom_palette_color (paint_data, color_index);
|
return funcs->custom_palette_color (paint_data, color_index, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,17 +34,6 @@
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HB_PAINT_PALETTE_INDEX_CUSTOM
|
|
||||||
*
|
|
||||||
* A palette index signifying that custom colors are in use.
|
|
||||||
* Such colors are fetched from the client using the
|
|
||||||
* custom-palette-color callback of the paint functions.
|
|
||||||
*
|
|
||||||
* Since: REPLACEME
|
|
||||||
**/
|
|
||||||
#define HB_PAINT_PALETTE_INDEX_CUSTOM 0xFFFFFFFF
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_paint_funcs_t:
|
* hb_paint_funcs_t:
|
||||||
*
|
*
|
||||||
|
@ -672,18 +661,21 @@ typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs,
|
||||||
* @funcs: paint functions object
|
* @funcs: paint functions object
|
||||||
* @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
|
* @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
|
||||||
* @color_index: the color index
|
* @color_index: the color index
|
||||||
|
* @color: (out): fetched color
|
||||||
* @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func()
|
* @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func()
|
||||||
*
|
*
|
||||||
* A virtual method for the #hb_paint_funcs_t to fetch a color from the custom
|
* A virtual method for the #hb_paint_funcs_t to fetch a color from the custom
|
||||||
* color palette.
|
* color palette.
|
||||||
*
|
*
|
||||||
* Return value: the color
|
* Return value: `true` if found, `false` otherwise
|
||||||
|
*
|
||||||
* Since: REPLACEME
|
* Since: REPLACEME
|
||||||
*/
|
*/
|
||||||
typedef hb_color_t (*hb_paint_custom_palette_color_func_t) (hb_paint_funcs_t *funcs,
|
typedef hb_bool_t (*hb_paint_custom_palette_color_func_t) (hb_paint_funcs_t *funcs,
|
||||||
void *paint_data,
|
void *paint_data,
|
||||||
unsigned int color_index,
|
unsigned int color_index,
|
||||||
void *user_data);
|
hb_color_t *color,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -974,9 +966,10 @@ HB_EXTERN void
|
||||||
hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
|
hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
|
||||||
hb_paint_composite_mode_t mode);
|
hb_paint_composite_mode_t mode);
|
||||||
|
|
||||||
HB_EXTERN hb_color_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
|
hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
|
||||||
unsigned int color_index);
|
unsigned int color_index,
|
||||||
|
hb_color_t *color);
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -138,10 +138,12 @@ struct hb_paint_funcs_t
|
||||||
{ func.pop_group (this, paint_data,
|
{ func.pop_group (this, paint_data,
|
||||||
mode,
|
mode,
|
||||||
!user_data ? nullptr : user_data->pop_group); }
|
!user_data ? nullptr : user_data->pop_group); }
|
||||||
hb_color_t custom_palette_color (void *paint_data,
|
bool custom_palette_color (void *paint_data,
|
||||||
unsigned int color_index)
|
unsigned int color_index,
|
||||||
|
hb_color_t *color)
|
||||||
{ return func.custom_palette_color (this, paint_data,
|
{ return func.custom_palette_color (this, paint_data,
|
||||||
color_index,
|
color_index,
|
||||||
|
color,
|
||||||
!user_data ? nullptr : user_data->custom_palette_color); }
|
!user_data ? nullptr : user_data->custom_palette_color); }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,6 @@ struct font_options_t : face_options_t
|
||||||
mutable double font_size_y = DEFAULT_FONT_SIZE;
|
mutable double font_size_y = DEFAULT_FONT_SIZE;
|
||||||
char *font_funcs = nullptr;
|
char *font_funcs = nullptr;
|
||||||
int ft_load_flags = 2;
|
int ft_load_flags = 2;
|
||||||
unsigned int palette = 0;
|
|
||||||
unsigned int named_instance = HB_FONT_NO_VAR_NAMED_INSTANCE;
|
unsigned int named_instance = HB_FONT_NO_VAR_NAMED_INSTANCE;
|
||||||
|
|
||||||
hb_font_t *font = nullptr;
|
hb_font_t *font = nullptr;
|
||||||
|
@ -289,7 +288,6 @@ font_options_t::add_options (option_parser_t *parser)
|
||||||
G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"},
|
G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"},
|
||||||
{"font-slant", 0, 0,
|
{"font-slant", 0, 0,
|
||||||
G_OPTION_ARG_DOUBLE, &this->slant, "Set synthetic slant (default: 0)", "slant ratio; eg. 0.2"},
|
G_OPTION_ARG_DOUBLE, &this->slant, "Set synthetic slant (default: 0)", "slant ratio; eg. 0.2"},
|
||||||
{"font-palette", 0, 0, G_OPTION_ARG_INT, &this->palette, "Set font palette (default: 0)", "index"},
|
|
||||||
{"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"},
|
{"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"},
|
||||||
{"sub-font", 0, G_OPTION_FLAG_HIDDEN,
|
{"sub-font", 0, G_OPTION_FLAG_HIDDEN,
|
||||||
G_OPTION_ARG_NONE, &this->sub_font, "Create a sub-font (default: false)", "boolean"},
|
G_OPTION_ARG_NONE, &this->sub_font, "Create a sub-font (default: false)", "boolean"},
|
||||||
|
|
|
@ -88,7 +88,8 @@ helper_cairo_use_hb_draw (const font_options_t *font_opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline cairo_scaled_font_t *
|
static inline cairo_scaled_font_t *
|
||||||
helper_cairo_create_scaled_font (const font_options_t *font_opts)
|
helper_cairo_create_scaled_font (const font_options_t *font_opts,
|
||||||
|
const view_options_t *view_opts)
|
||||||
{
|
{
|
||||||
hb_font_t *font = font_opts->font;
|
hb_font_t *font = font_opts->font;
|
||||||
bool use_hb_draw = true;
|
bool use_hb_draw = true;
|
||||||
|
@ -123,7 +124,33 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
|
||||||
cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
|
cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
|
||||||
cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
|
cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
|
||||||
#ifdef CAIRO_COLOR_PALETTE_DEFAULT
|
#ifdef CAIRO_COLOR_PALETTE_DEFAULT
|
||||||
cairo_font_options_set_color_palette (font_options, font_opts->palette);
|
cairo_font_options_set_color_palette (font_options, view_opts->palette);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
|
||||||
|
if (view_opts->custom_palette)
|
||||||
|
{
|
||||||
|
char **entries = g_strsplit (view_opts->custom_palette, ",", -1);
|
||||||
|
unsigned idx = 0;
|
||||||
|
for (unsigned i = 0; entries[i]; i++)
|
||||||
|
{
|
||||||
|
const char *p = strchr (entries[i], '=');
|
||||||
|
if (!p)
|
||||||
|
p = entries[i];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sscanf (entries[i], "%u", &idx);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned fr, fg, fb, fa;
|
||||||
|
fr = fg = fb = fa = 0;
|
||||||
|
if (parse_color (p, fr, fg,fb, fa))
|
||||||
|
cairo_font_options_set_custom_palette_color (font_options, idx, fr / 255., fg / 255., fb / 255., fa / 255.);
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
g_strfreev (entries);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (cairo_face,
|
cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (cairo_face,
|
||||||
|
@ -492,12 +519,12 @@ helper_cairo_create_context (double w, double h,
|
||||||
|
|
||||||
unsigned int fr, fg, fb, fa, br, bg, bb, ba;
|
unsigned int fr, fg, fb, fa, br, bg, bb, ba;
|
||||||
const char *color;
|
const char *color;
|
||||||
br = bg = bb = 0; ba = 255;
|
br = bg = bb = ba = 255;
|
||||||
color = view_opts->back ? view_opts->back : DEFAULT_BACK;
|
color = view_opts->back ? view_opts->back : DEFAULT_BACK;
|
||||||
sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &br, &bg, &bb, &ba);
|
parse_color (color, br, bg, bb, ba);
|
||||||
fr = fg = fb = 0; fa = 255;
|
fr = fg = fb = 0; fa = 255;
|
||||||
color = view_opts->fore ? view_opts->fore : DEFAULT_FORE;
|
color = view_opts->fore ? view_opts->fore : DEFAULT_FORE;
|
||||||
sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa);
|
parse_color (color, fr, fg, fb, fa);
|
||||||
|
|
||||||
if (content == CAIRO_CONTENT_ALPHA)
|
if (content == CAIRO_CONTENT_ALPHA)
|
||||||
{
|
{
|
||||||
|
|
|
@ -242,4 +242,44 @@ __inline float scalbnf (float x, int exp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
parse_color (const char *s,
|
||||||
|
unsigned &r,
|
||||||
|
unsigned &g,
|
||||||
|
unsigned &b,
|
||||||
|
unsigned &a)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
while (*s == ' ') s++;
|
||||||
|
if (*s == '#') s++;
|
||||||
|
|
||||||
|
unsigned sr, sg, sb, sa;
|
||||||
|
sa = 255;
|
||||||
|
if (sscanf (s, "%2x%2x%2x%2x", &sr, &sg, &sb, &sa) <= 2)
|
||||||
|
{
|
||||||
|
if (sscanf (s, "%1x%1x%1x%1x", &sr, &sg, &sb, &sa) >= 3)
|
||||||
|
{
|
||||||
|
sr *= 17;
|
||||||
|
sg *= 17;
|
||||||
|
sb *= 17;
|
||||||
|
sa *= 17;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
r = sr;
|
||||||
|
g = sg;
|
||||||
|
b = sb;
|
||||||
|
a = sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -131,7 +131,8 @@ view_cairo_t::render (const font_options_t *font_opts)
|
||||||
w = MAX (w, x_sign * x_advance);
|
w = MAX (w, x_sign * x_advance);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts);
|
cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts,
|
||||||
|
this);
|
||||||
|
|
||||||
/* See if font needs color. */
|
/* See if font needs color. */
|
||||||
cairo_content_t content = CAIRO_CONTENT_ALPHA;
|
cairo_content_t content = CAIRO_CONTENT_ALPHA;
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct view_options_t
|
||||||
{
|
{
|
||||||
g_free (fore);
|
g_free (fore);
|
||||||
g_free (back);
|
g_free (back);
|
||||||
|
g_free (custom_palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_options (option_parser_t *parser);
|
void add_options (option_parser_t *parser);
|
||||||
|
@ -46,6 +47,8 @@ struct view_options_t
|
||||||
hb_bool_t annotate = false;
|
hb_bool_t annotate = false;
|
||||||
char *fore = nullptr;
|
char *fore = nullptr;
|
||||||
char *back = nullptr;
|
char *back = nullptr;
|
||||||
|
unsigned int palette = 0;
|
||||||
|
char *custom_palette = nullptr;
|
||||||
double line_space = 0;
|
double line_space = 0;
|
||||||
bool have_font_extents = false;
|
bool have_font_extents = false;
|
||||||
struct font_extents_t {
|
struct font_extents_t {
|
||||||
|
@ -108,6 +111,8 @@ view_options_t::add_options (option_parser_t *parser)
|
||||||
{"annotate", 0, 0, G_OPTION_ARG_NONE, &this->annotate, "Annotate output rendering", nullptr},
|
{"annotate", 0, 0, G_OPTION_ARG_NONE, &this->annotate, "Annotate output rendering", nullptr},
|
||||||
{"background", 0, 0, G_OPTION_ARG_STRING, &this->back, "Set background color (default: " DEFAULT_BACK ")", "rrggbb/rrggbbaa"},
|
{"background", 0, 0, G_OPTION_ARG_STRING, &this->back, "Set background color (default: " DEFAULT_BACK ")", "rrggbb/rrggbbaa"},
|
||||||
{"foreground", 0, 0, G_OPTION_ARG_STRING, &this->fore, "Set foreground color (default: " DEFAULT_FORE ")", "rrggbb/rrggbbaa"},
|
{"foreground", 0, 0, G_OPTION_ARG_STRING, &this->fore, "Set foreground color (default: " DEFAULT_FORE ")", "rrggbb/rrggbbaa"},
|
||||||
|
{"font-palette", 0, 0, G_OPTION_ARG_INT, &this->palette, "Set font palette (default: 0)", "index"},
|
||||||
|
{"custom-palette", 0, 0, G_OPTION_ARG_STRING, &this->custom_palette, "Custom palette", "comma-separated colors"},
|
||||||
{"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &this->line_space, "Set space between lines (default: 0)", "units"},
|
{"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &this->line_space, "Set space between lines (default: 0)", "units"},
|
||||||
{"font-extents", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_extents, "Set font ascent/descent/line-gap (default: auto)","one to three numbers"},
|
{"font-extents", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_extents, "Set font ascent/descent/line-gap (default: auto)","one to three numbers"},
|
||||||
{"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output (default: " G_STRINGIFY(DEFAULT_MARGIN) ")","one to four numbers"},
|
{"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output (default: " G_STRINGIFY(DEFAULT_MARGIN) ")","one to four numbers"},
|
||||||
|
|
Loading…
Reference in New Issue