diff options
Diffstat (limited to 'util/helper-cairo.hh')
-rw-r--r-- | util/helper-cairo.hh | 120 |
1 files changed, 49 insertions, 71 deletions
diff --git a/util/helper-cairo.hh b/util/helper-cairo.hh index b8d461224..a8463de4d 100644 --- a/util/helper-cairo.hh +++ b/util/helper-cairo.hh @@ -29,10 +29,13 @@ #include "view-options.hh" #include "output-options.hh" +#ifdef HAVE_CAIRO_FT +# include "helper-cairo-ft.hh" +#endif +#include "helper-cairo-user.hh" -#include <cairo-ft.h> -#include <hb-ft.h> -#include FT_MULTIPLE_MASTERS_H +#include <cairo.h> +#include <hb.h> #include "helper-cairo-ansi.hh" #ifdef CAIRO_HAS_SVG_SURFACE @@ -65,74 +68,41 @@ _cairo_eps_surface_create_for_stream (cairo_write_func_t write_func, # endif #endif - -static FT_Library ft_library; - -#ifdef HAVE_ATEXIT -static inline -void free_ft_library () +static inline bool +helper_cairo_use_hb_draw (const font_options_t *font_opts) { - FT_Done_FreeType (ft_library); -} + const char *env = getenv ("HB_DRAW"); + if (!env) +#if 1 + /* Following branch disabled because we prefer our + * OpenType extensions working, ie going through hb-draw, + * over avoiding the obscure cairo bug. */ + return true; +#else + /* Older cairo had a bug in rendering COLRv0 fonts in + * right-to-left direction. */ + return cairo_version () >= CAIRO_VERSION_ENCODE (1, 17, 5); #endif + return atoi (env); +} + static inline cairo_scaled_font_t * helper_cairo_create_scaled_font (const font_options_t *font_opts) { hb_font_t *font = hb_font_reference (font_opts->font); +#ifdef HAVE_CAIRO_FT + bool use_hb_draw = helper_cairo_use_hb_draw (font_opts); cairo_font_face_t *cairo_face; - /* We cannot use the FT_Face from hb_font_t, as doing so will confuse hb_font_t because - * cairo will reset the face size. As such, create new face... - * TODO Perhaps add API to hb-ft to encapsulate this code. */ - FT_Face ft_face = nullptr;//hb_ft_font_get_face (font); - if (!ft_face) - { - if (!ft_library) - { - FT_Init_FreeType (&ft_library); -#ifdef HAVE_ATEXIT - atexit (free_ft_library); -#endif - } - - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (font_opts->blob, &blob_length); - - if (FT_New_Memory_Face (ft_library, - (const FT_Byte *) blob_data, - blob_length, - font_opts->face_index, - &ft_face)) - fail (false, "FT_New_Memory_Face fail"); - } - if (!ft_face) - { - /* This allows us to get some boxes at least... */ - cairo_face = cairo_toy_font_face_create ("@cairo:sans", - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_NORMAL); - } + if (use_hb_draw) + cairo_face = helper_cairo_create_user_font_face (font_opts); else - { -#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES - unsigned int num_coords; - const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); - if (num_coords) - { - FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed)); - if (ft_coords) - { - for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] << 2; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); - free (ft_coords); - } - } + cairo_face = helper_cairo_create_ft_font_face (font_opts); +#else + cairo_font_face_t *cairo_face = helper_cairo_create_user_font_face (font_opts); #endif - cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, font_opts->ft_load_flags); - } cairo_matrix_t ctm, font_matrix; cairo_font_options_t *font_options; @@ -140,6 +110,11 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts) cairo_matrix_init_scale (&font_matrix, font_opts->font_size_x, font_opts->font_size_y); +#ifdef HAVE_CAIRO_FT + if (!use_hb_draw) + font_matrix.xy = -font_opts->slant * font_opts->font_size_x; +#endif + font_options = cairo_font_options_create (); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); @@ -165,17 +140,14 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts) static inline bool helper_cairo_scaled_font_has_color (cairo_scaled_font_t *scaled_font) { - bool ret = false; -#ifdef FT_HAS_COLOR - FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font); - if (ft_face) - { - if (FT_HAS_COLOR (ft_face)) - ret = true; - cairo_ft_scaled_font_unlock_face (scaled_font); - } +#ifdef HAVE_CAIRO_FT + if (helper_cairo_user_font_face_has_data (cairo_scaled_font_get_font_face (scaled_font))) + return helper_cairo_user_scaled_font_has_color (scaled_font); + else + return helper_cairo_ft_scaled_font_has_color (scaled_font); +#else + return helper_cairo_user_scaled_font_has_color (scaled_font); #endif - return ret; } @@ -427,11 +399,11 @@ static const char *helper_cairo_supported_formats[] = }; template <typename view_options_t, - typename output_options_t> + typename output_options_type> static inline cairo_t * helper_cairo_create_context (double w, double h, view_options_t *view_opts, - output_options_t *out_opts, + output_options_type *out_opts, cairo_content_t content) { cairo_surface_t *(*constructor) (cairo_write_func_t write_func, @@ -460,6 +432,12 @@ helper_cairo_create_context (double w, double h, extension = "png"; protocol = image_protocol_t::ITERM2; } + else if ((name = getenv ("TERM_PROGRAM")) != nullptr && + 0 == g_ascii_strcasecmp (name, "WezTerm")) + { + extension = "png"; + protocol = image_protocol_t::ITERM2; + } else if ((name = getenv ("TERM")) != nullptr && 0 == g_ascii_strcasecmp (name, "xterm-kitty")) { |