Skip to content

Commit 2cffdd6

Browse files
committed
Fix RGB/BGR handling
1 parent b9a5972 commit 2cffdd6

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

kitty/freetype.c

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ typedef struct {
309309
size_t start_x, width, stride;
310310
size_t rows;
311311
FT_Pixel_Mode pixel_mode;
312+
bool bgr;
312313
bool needs_free;
313314
unsigned int factor, right_edge;
314315
int bitmap_left, bitmap_top;
@@ -322,14 +323,44 @@ free_processed_bitmap(ProcessedBitmap *bm) {
322323
}
323324
}
324325

326+
static inline bool
327+
is_symbol_visible(ProcessedBitmap *ans, size_t x, size_t y) {
328+
unsigned char *s = ans->buf + x + y * ans->stride;
329+
float color = 255.0;
330+
switch (ans->pixel_mode) {
331+
case FT_PIXEL_MODE_GRAY:
332+
color = (float)s[0];
333+
break;
334+
case FT_PIXEL_MODE_LCD:
335+
#define C(red, green, blue) ((float)s[red])*0.3 + ((float)s[green])*0.59 + ((float)s[blue])*0.11
336+
if (!ans->bgr)
337+
color = C(0, 1, 2);
338+
else
339+
color = C(2, 1, 0);
340+
#undef C
341+
break;
342+
case FT_PIXEL_MODE_LCD_V:
343+
#define C(red, green, blue) ((float)s[red])*0.3 + ((float)s[green * ans->stride])*0.59 + ((float)s[blue * ans->stride])*0.11
344+
if (!ans->bgr)
345+
color = C(0, 1, 2);
346+
else
347+
color = C(2, 1, 0);
348+
#undef C
349+
break;
350+
default:
351+
return true;
352+
}
353+
return color > 200.0;
354+
}
355+
325356
static inline void
326357
trim_borders(ProcessedBitmap *ans, size_t extra) {
327358
bool column_has_text = false;
328359

329360
// Trim empty columns from the right side of the bitmap
330361
for (ssize_t x = ans->width - 1; !column_has_text && x > -1 && extra > 0; x--) {
331362
for (size_t y = 0; y < ans->rows && !column_has_text; y++) {
332-
if (ans->buf[x + y * ans->stride] > 200) column_has_text = true; // TODO
363+
if (is_symbol_visible(ans, x, y)) column_has_text = true;
333364
}
334365
if (!column_has_text) { ans->width--; extra--; }
335366
}
@@ -528,7 +559,7 @@ copy_lcd_bitmap(uint8_t *src, pixel* dest, Region *src_rect, Region *dest_rect,
528559
}
529560

530561
static inline void
531-
place_bitmap_in_canvas(pixel *cell, ProcessedBitmap *bm, size_t cell_width, size_t cell_height, float x_offset, float y_offset, size_t baseline, bool bgr) {
562+
place_bitmap_in_canvas(pixel *cell, ProcessedBitmap *bm, size_t cell_width, size_t cell_height, float x_offset, float y_offset, size_t baseline) {
532563
// We want the glyph to be positioned inside the cell based on the bearingX
533564
// and bearingY values, making sure that it does not overflow the cell.
534565

@@ -558,9 +589,9 @@ place_bitmap_in_canvas(pixel *cell, ProcessedBitmap *bm, size_t cell_width, size
558589
if (bm->pixel_mode == FT_PIXEL_MODE_BGRA) {
559590
copy_color_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width);
560591
} else if (bm->pixel_mode == FT_PIXEL_MODE_LCD) {
561-
copy_lcd_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bgr);
592+
copy_lcd_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bm->bgr);
562593
} else if (bm->pixel_mode == FT_PIXEL_MODE_LCD_V) {
563-
// copy_lcd_v_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bgr);
594+
// copy_lcd_v_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bm->bgr);
564595
// TODO: implement it
565596
} else render_alpha_mask(bm->buf, cell, &src, &dest, bm->stride, cell_width);
566597
}
@@ -576,6 +607,7 @@ render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *inf
576607
unsigned int canvas_width = cell_width * num_cells;
577608
for (unsigned int i = 0; i < num_glyphs; i++) {
578609
bm = EMPTY_PBM;
610+
bm.bgr = (self->rgba == FC_RGBA_BGR || self->rgba == FC_RGBA_VBGR);
579611
if (*was_colored) {
580612
if (!render_color_bitmap(self, info[i].codepoint, &bm, cell_width, cell_height, num_cells, baseline)) {
581613
if (PyErr_Occurred()) PyErr_Print();
@@ -589,7 +621,7 @@ render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t *inf
589621
x_offset = x + (float)positions[i].x_offset / 64.0f;
590622
y = (float)positions[i].y_offset / 64.0f;
591623
if ((*was_colored || self->face->glyph->metrics.width > 0) && bm.width > 0) {
592-
place_bitmap_in_canvas(canvas, &bm, canvas_width, cell_height, x_offset, y, baseline, (self->rgba == FC_RGBA_BGR));
624+
place_bitmap_in_canvas(canvas, &bm, canvas_width, cell_height, x_offset, y, baseline);
593625
}
594626
x += (float)positions[i].x_advance / 64.0f;
595627
free_processed_bitmap(&bm);
@@ -654,8 +686,9 @@ render_simple_text_impl(PyObject *s, const char *text, unsigned int baseline) {
654686
if (error) continue;
655687
FT_Bitmap *bitmap = &self->face->glyph->bitmap;
656688
pbm = EMPTY_PBM;
689+
pbm.bgr = (self->rgba == FC_RGBA_BGR || self->rgba == FC_RGBA_VBGR);
657690
populate_processed_bitmap(self->face->glyph, bitmap, &pbm, false);
658-
place_bitmap_in_canvas(canvas, &pbm, canvas_width, canvas_height, pen_x, 0, baseline, (self->rgba == FC_RGBA_BGR));
691+
place_bitmap_in_canvas(canvas, &pbm, canvas_width, canvas_height, pen_x, 0, baseline);
659692
pen_x += self->face->glyph->advance.x >> 6;
660693
}
661694
ans.width = pen_x; ans.height = canvas_height;

0 commit comments

Comments
 (0)