mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-08-31 22:32:45 +00:00
Fix color render path for non-emoji codepoints on color-capable faces
render_group() used has_emoji_presentation() for all codepoints, but that only makes sense for emoji (VS15/VS16 selectors). Non-emoji codepoints now use face_has_color() instead, and *was_colored is set from actual render output rather than preset before rendering.
This commit is contained in:
parent
4483a6c110
commit
2f93de3d68
4 changed files with 26 additions and 6 deletions
|
|
@ -522,6 +522,11 @@ face_apply_scaling(PyObject *f, const FONTS_DATA_HANDLE fg) {
|
|||
return set_size_for_face(f, 0, false, fg);
|
||||
}
|
||||
|
||||
bool
|
||||
face_has_color(PyObject *f) {
|
||||
return CTFontSupportsColorGlyphs(((CTFace*)f)->ct_font);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
set_size(CTFace *self, PyObject *args) {
|
||||
double font_sz_in_pts, dpi_x, dpi_y;
|
||||
|
|
|
|||
|
|
@ -1200,7 +1200,13 @@ render_group(
|
|||
is_only_filled_boxes = true;
|
||||
for (unsigned i = 1; i < num_glyphs && is_only_filled_boxes; i++) if (global_glyph_render_scratch.glyphs[i] != box_glyph_id) is_only_filled_boxes = false;
|
||||
}
|
||||
bool was_colored = !is_only_filled_boxes && has_emoji_presentation(cpu_cells, global_glyph_render_scratch.lc);
|
||||
const ListOfChars *lc = global_glyph_render_scratch.lc;
|
||||
// For emoji, honor the text/emoji presentation selectors (VS15/VS16); for a
|
||||
// non-emoji codepoint on a color-capable face (e.g. an icon font mapped via
|
||||
// symbol_map), use the color render path.
|
||||
bool first_is_emoji = lc->count && char_props_for(lc->chars[0]).is_emoji;
|
||||
bool was_colored = !is_only_filled_boxes && (
|
||||
first_is_emoji ? has_emoji_presentation(cpu_cells, lc) : face_has_color(font->face));
|
||||
GlyphRenderInfo ri = {0};
|
||||
pixel *canvas = rendering_in_smaller_area && canvas_width != scaled_canvas_width ? scratch : fg->canvas.buf;
|
||||
if (is_only_filled_boxes) { // special case rendering of █ for tests
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ typedef void (*free_extra_data_func)(void*);
|
|||
StringCanvas render_simple_text_impl(PyObject *s, const char *text, unsigned int baseline);
|
||||
StringCanvas render_simple_text(FONTS_DATA_HANDLE fg_, const char *text);
|
||||
bool face_apply_scaling(PyObject*face, const FONTS_DATA_HANDLE fg);
|
||||
bool face_has_color(PyObject *face);
|
||||
|
||||
bool
|
||||
add_font_name_record(PyObject *table, uint16_t platform_id, uint16_t encoding_id, uint16_t language_id, uint16_t name_id, const char *string, uint16_t string_len);
|
||||
|
|
|
|||
|
|
@ -246,6 +246,11 @@ face_apply_scaling(PyObject *f, const FONTS_DATA_HANDLE fg) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
face_has_color(PyObject *f) {
|
||||
return ((Face*)f)->has_color;
|
||||
}
|
||||
|
||||
static bool
|
||||
init_ft_face(Face *self, PyObject *path, int hinting, int hintstyle, long index, FONTS_DATA_HANDLE fg) {
|
||||
copy_face_metrics(self);
|
||||
|
|
@ -964,24 +969,27 @@ static const ProcessedBitmap EMPTY_PBM = {.factor = 1};
|
|||
bool
|
||||
render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *info, hb_glyph_position_t *positions, unsigned int num_glyphs, pixel *canvas, unsigned int cell_width, unsigned int cell_height, unsigned int num_cells, unsigned int baseline, bool *was_colored, FONTS_DATA_HANDLE fg, GlyphRenderInfo *ri) {
|
||||
Face *self = (Face*)f;
|
||||
bool is_emoji = *was_colored; *was_colored = is_emoji && self->has_color;
|
||||
// *was_colored is an incoming hint; it is set on output to reflect whether
|
||||
// any glyph was actually rendered as color.
|
||||
bool want_color = *was_colored && self->has_color;
|
||||
*was_colored = false;
|
||||
float x = 0.f, y = 0.f;
|
||||
ProcessedBitmap bm;
|
||||
unsigned int canvas_width = cell_width * num_cells;
|
||||
GlyphColorType colored;
|
||||
for (unsigned int i = 0; i < num_glyphs; i++) {
|
||||
bm = EMPTY_PBM;
|
||||
bool colored_glyph = false;
|
||||
// dont load the space glyph since loading it fails for some fonts/sizes and it is anyway to be rendered as a blank
|
||||
if (info[i].codepoint != self->space_glyph_id) {
|
||||
if (*was_colored && (colored = glyph_color_type(self, info[i].codepoint)) != NOT_COLORED) {
|
||||
if (want_color && (colored = glyph_color_type(self, info[i].codepoint)) != NOT_COLORED) {
|
||||
if (!render_color_bitmap(self, info[i].codepoint, &bm, cell_width, cell_height, num_cells, baseline)) {
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
if (!render_bitmap(self, info[i].codepoint, &bm, cell_width, cell_height, num_cells, bold, italic, true, fg)) {
|
||||
free_processed_bitmap(&bm);
|
||||
return false;
|
||||
}
|
||||
*was_colored = false;
|
||||
}
|
||||
} else { colored_glyph = true; *was_colored = true; }
|
||||
} else {
|
||||
if (!render_bitmap(self, info[i].codepoint, &bm, cell_width, cell_height, num_cells, bold, italic, true, fg)) {
|
||||
free_processed_bitmap(&bm);
|
||||
|
|
@ -992,7 +1000,7 @@ render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *inf
|
|||
float x_offset = x + (float)positions[i].x_offset / 64.0f;
|
||||
y = (float)positions[i].y_offset / 64.0f;
|
||||
if (debug_placement) printf("%d: x=%f canvas: %u", i, x_offset, canvas_width);
|
||||
if ((*was_colored || self->face->glyph->metrics.width > 0) && bm.width > 0) {
|
||||
if ((colored_glyph || self->face->glyph->metrics.width > 0) && bm.width > 0) {
|
||||
place_bitmap_in_canvas(canvas, &bm, canvas_width, cell_height, x_offset, y, baseline, i, 0xffffff, 0, 0);
|
||||
}
|
||||
if (debug_placement) printf(" adv: %f\n", (float)positions[i].x_advance / 64.0f);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue