[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 {
|
struct finalize_closure_t {
|
||||||
void (*callback)(finalize_closure_t *);
|
void (*callback)(finalize_closure_t *);
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
cairo_write_func_t write_func;
|
cairo_write_func_t write_func;
|
||||||
void *closure;
|
void *closure;
|
||||||
|
image_protocol_t protocol;
|
||||||
};
|
};
|
||||||
static cairo_user_data_key_t finalize_closure_key;
|
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,
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height,
|
double height,
|
||||||
cairo_content_t content)
|
cairo_content_t content,
|
||||||
|
image_protocol_t protocol HB_UNUSED)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
int w = ceil (width);
|
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
|
#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
|
static void
|
||||||
finalize_png (finalize_closure_t *closure)
|
finalize_png (finalize_closure_t *closure)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
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,
|
status = cairo_surface_write_to_png_stream (closure->surface,
|
||||||
closure->write_func,
|
closure->write_func,
|
||||||
closure->closure);
|
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)
|
if (status != CAIRO_STATUS_SUCCESS)
|
||||||
fail (false, "Failed to write output: %s",
|
fail (false, "Failed to write output: %s",
|
||||||
cairo_status_to_string (status));
|
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 *
|
static cairo_surface_t *
|
||||||
|
@ -259,7 +311,8 @@ _cairo_png_surface_create_for_stream (cairo_write_func_t write_func,
|
||||||
void *closure,
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height,
|
double height,
|
||||||
cairo_content_t content)
|
cairo_content_t content,
|
||||||
|
image_protocol_t protocol)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
int w = ceil (width);
|
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->surface = surface;
|
||||||
png_closure->write_func = write_func;
|
png_closure->write_func = write_func;
|
||||||
png_closure->closure = closure;
|
png_closure->closure = closure;
|
||||||
|
png_closure->protocol = protocol;
|
||||||
|
|
||||||
if (cairo_surface_set_user_data (surface,
|
if (cairo_surface_set_user_data (surface,
|
||||||
&finalize_closure_key,
|
&finalize_closure_key,
|
||||||
|
@ -352,13 +406,30 @@ helper_cairo_create_context (double w, double h,
|
||||||
void *closure,
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height,
|
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;
|
const char *extension = out_opts->output_format;
|
||||||
if (!extension) {
|
if (!extension) {
|
||||||
#if HAVE_ISATTY
|
#if HAVE_ISATTY
|
||||||
if (isatty (fileno (out_opts->get_file_handle ())))
|
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";
|
extension = "ansi";
|
||||||
|
#else
|
||||||
|
extension = "ansi";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -419,7 +490,7 @@ helper_cairo_create_context (double w, double h,
|
||||||
if (constructor)
|
if (constructor)
|
||||||
surface = constructor (stdio_write_func, f, w, h);
|
surface = constructor (stdio_write_func, f, w, h);
|
||||||
else if (constructor2)
|
else if (constructor2)
|
||||||
surface = constructor2 (stdio_write_func, f, w, h, content);
|
surface = constructor2 (stdio_write_func, f, w, h, content, protocol);
|
||||||
else
|
else
|
||||||
fail (false, "Unknown output format `%s'; supported formats are: %s%s",
|
fail (false, "Unknown output format `%s'; supported formats are: %s%s",
|
||||||
extension,
|
extension,
|
||||||
|
|
Loading…
Reference in New Issue