[hb-view] Support iTerm2 inline images protocol
https://github.com/harfbuzz/harfbuzz/issues/2758
This commit is contained in:
parent
743baf3543
commit
f7d5889b3e
|
@ -175,11 +175,17 @@ helper_cairo_scaled_font_has_color (cairo_scaled_font_t *scaled_font)
|
|||
}
|
||||
|
||||
|
||||
enum class image_protocol_t {
|
||||
NONE = 0,
|
||||
ITERM2,
|
||||
};
|
||||
|
||||
struct finalize_closure_t {
|
||||
void (*callback)(finalize_closure_t *);
|
||||
cairo_surface_t *surface;
|
||||
cairo_write_func_t write_func;
|
||||
void *closure;
|
||||
image_protocol_t protocol;
|
||||
};
|
||||
static cairo_user_data_key_t finalize_closure_key;
|
||||
|
||||
|
@ -201,7 +207,8 @@ _cairo_ansi_surface_create_for_stream (cairo_write_func_t write_func,
|
|||
void *closure,
|
||||
double width,
|
||||
double height,
|
||||
cairo_content_t content)
|
||||
cairo_content_t content,
|
||||
image_protocol_t protocol HB_UNUSED)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
int w = ceil (width);
|
||||
|
@ -242,16 +249,61 @@ _cairo_ansi_surface_create_for_stream (cairo_write_func_t write_func,
|
|||
|
||||
#ifdef CAIRO_HAS_PNG_FUNCTIONS
|
||||
|
||||
static cairo_status_t
|
||||
byte_array_write_func (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int size)
|
||||
{
|
||||
g_byte_array_append ((GByteArray *) closure, data, size);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
finalize_png (finalize_closure_t *closure)
|
||||
{
|
||||
cairo_status_t status;
|
||||
status = cairo_surface_write_to_png_stream (closure->surface,
|
||||
closure->write_func,
|
||||
closure->closure);
|
||||
GByteArray *bytes;
|
||||
GString *string;
|
||||
gchar *base64;
|
||||
size_t base64_len;
|
||||
|
||||
if (closure->protocol == image_protocol_t::NONE)
|
||||
{
|
||||
status = cairo_surface_write_to_png_stream (closure->surface,
|
||||
closure->write_func,
|
||||
closure->closure);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes = g_byte_array_new ();
|
||||
status = cairo_surface_write_to_png_stream (closure->surface,
|
||||
byte_array_write_func,
|
||||
bytes);
|
||||
}
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
fail (false, "Failed to write output: %s",
|
||||
cairo_status_to_string (status));
|
||||
|
||||
if (closure->protocol == image_protocol_t::NONE)
|
||||
return;
|
||||
|
||||
base64 = g_base64_encode (bytes->data, bytes->len);
|
||||
base64_len = strlen (base64);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
if (closure->protocol == image_protocol_t::ITERM2)
|
||||
{
|
||||
/* https://iterm2.com/documentation-images.html */
|
||||
g_string_printf (string, "\033]1337;File=inline=1;size=%zu:%s\a\n",
|
||||
base64_len, base64);
|
||||
}
|
||||
|
||||
closure->write_func (closure->closure, (unsigned char *) string->str, string->len);
|
||||
|
||||
g_byte_array_unref (bytes);
|
||||
g_free (base64);
|
||||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
|
@ -259,7 +311,8 @@ _cairo_png_surface_create_for_stream (cairo_write_func_t write_func,
|
|||
void *closure,
|
||||
double width,
|
||||
double height,
|
||||
cairo_content_t content)
|
||||
cairo_content_t content,
|
||||
image_protocol_t protocol)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
int w = ceil (width);
|
||||
|
@ -287,6 +340,7 @@ _cairo_png_surface_create_for_stream (cairo_write_func_t write_func,
|
|||
png_closure->surface = surface;
|
||||
png_closure->write_func = write_func;
|
||||
png_closure->closure = closure;
|
||||
png_closure->protocol = protocol;
|
||||
|
||||
if (cairo_surface_set_user_data (surface,
|
||||
&finalize_closure_key,
|
||||
|
@ -352,13 +406,30 @@ helper_cairo_create_context (double w, double h,
|
|||
void *closure,
|
||||
double width,
|
||||
double height,
|
||||
cairo_content_t content) = nullptr;
|
||||
cairo_content_t content,
|
||||
image_protocol_t protocol) = nullptr;
|
||||
|
||||
image_protocol_t protocol = image_protocol_t::NONE;
|
||||
const char *extension = out_opts->output_format;
|
||||
if (!extension) {
|
||||
#if HAVE_ISATTY
|
||||
if (isatty (fileno (out_opts->get_file_handle ())))
|
||||
{
|
||||
#ifdef CAIRO_HAS_PNG_FUNCTIONS
|
||||
const char *name;
|
||||
/* https://gitlab.com/gnachman/iterm2/-/issues/7154 */
|
||||
if ((name = getenv ("LC_TERMINAL")) != nullptr &&
|
||||
0 == g_ascii_strcasecmp (name, "iTerm2"))
|
||||
{
|
||||
extension = "png";
|
||||
protocol = image_protocol_t::ITERM2;
|
||||
}
|
||||
else
|
||||
extension = "ansi";
|
||||
#else
|
||||
extension = "ansi";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
@ -419,7 +490,7 @@ helper_cairo_create_context (double w, double h,
|
|||
if (constructor)
|
||||
surface = constructor (stdio_write_func, f, w, h);
|
||||
else if (constructor2)
|
||||
surface = constructor2 (stdio_write_func, f, w, h, content);
|
||||
surface = constructor2 (stdio_write_func, f, w, h, content, protocol);
|
||||
else
|
||||
fail (false, "Unknown output format `%s'; supported formats are: %s%s",
|
||||
extension,
|
||||
|
|
Loading…
Reference in New Issue