Skip to content

Commit 29932ff

Browse files
committed
Add vertical subpixel rendering
1 parent 5ada290 commit 29932ff

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

kitty/freetype.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -375,16 +375,19 @@ trim_borders(ProcessedBitmap *ans, size_t extra) {
375375
static inline void
376376
populate_processed_bitmap(FT_GlyphSlotRec *slot, FT_Bitmap *bitmap, ProcessedBitmap *ans, bool copy_buf) {
377377
ans->stride = bitmap->pitch < 0 ? -bitmap->pitch : bitmap->pitch;
378-
ans->rows = bitmap->rows;
379378
if (copy_buf) {
380-
ans->buf = calloc(ans->rows, ans->stride);
379+
ans->buf = calloc(bitmap->rows, ans->stride);
381380
if (!ans->buf) fatal("Out of memory");
382381
ans->needs_free = true;
383-
memcpy(ans->buf, bitmap->buffer, ans->rows * ans->stride);
382+
memcpy(ans->buf, bitmap->buffer, bitmap->rows * ans->stride);
384383
} else ans->buf = bitmap->buffer;
385-
ans->start_x = 0; ans->width = bitmap->width;
384+
ans->start_x = 0; ans->width = bitmap->width; ans->rows = bitmap->rows;
386385
ans->pixel_mode = bitmap->pixel_mode;
387386
ans->bitmap_top = slot->bitmap_top; ans->bitmap_left = slot->bitmap_left;
387+
if (ans->pixel_mode == FT_PIXEL_MODE_LCD)
388+
ans->width /= 3;
389+
else if (ans->pixel_mode == FT_PIXEL_MODE_LCD_V)
390+
ans->rows /= 3;
388391
}
389392

390393
static inline bool
@@ -423,12 +426,6 @@ render_bitmap(Face *self, int glyph_id, ProcessedBitmap *ans, unsigned int cell_
423426
}
424427
populate_processed_bitmap(self->face->glyph, &bitmap, ans, true);
425428
FT_Bitmap_Done(library, &bitmap);
426-
} else if (self->face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) {
427-
populate_processed_bitmap(self->face->glyph, &self->face->glyph->bitmap, ans, false);
428-
ans->width /= 3;
429-
} else if (self->face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) {
430-
populate_processed_bitmap(self->face->glyph, &self->face->glyph->bitmap, ans, false);
431-
// TODO: tune ans->rows, as it's 3 times biger than the actual height
432429
} else {
433430
populate_processed_bitmap(self->face->glyph, &self->face->glyph->bitmap, ans, false);
434431
}
@@ -561,6 +558,23 @@ copy_lcd_bitmap(uint8_t *src, pixel* dest, Region *src_rect, Region *dest_rect,
561558
}
562559
}
563560

561+
static inline void
562+
copy_lcd_v_bitmap(uint8_t *src, pixel* dest, Region *src_rect, Region *dest_rect, size_t src_stride, size_t dest_stride, bool bgr) {
563+
for (size_t sr = src_rect->top, dr = dest_rect->top; sr < src_rect->bottom && dr < dest_rect->bottom; sr++, dr++) {
564+
pixel *d = dest + dest_stride * dr;
565+
uint8_t *s = src + 3 * src_stride * sr;
566+
for(size_t sc = src_rect->left, dc = dest_rect->left; sc < src_rect->right && dc < dest_rect->right; sc++, dc++) {
567+
uint8_t *rgb = s + sc;
568+
#define C(idx, shift) ( rgb[src_stride * idx] << shift)
569+
if (!bgr)
570+
d[dc] = C(0, 24) | C(1, 16) | C(2, 8) | 0xff;
571+
else
572+
d[dc] = C(2, 24) | C(1, 16) | C(0, 8) | 0xff;
573+
#undef C
574+
}
575+
}
576+
}
577+
564578
static inline void
565579
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) {
566580
// We want the glyph to be positioned inside the cell based on the bearingX
@@ -594,8 +608,7 @@ place_bitmap_in_canvas(pixel *cell, ProcessedBitmap *bm, size_t cell_width, size
594608
} else if (bm->pixel_mode == FT_PIXEL_MODE_LCD) {
595609
copy_lcd_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bm->bgr);
596610
} else if (bm->pixel_mode == FT_PIXEL_MODE_LCD_V) {
597-
// copy_lcd_v_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bm->bgr);
598-
// TODO: implement it
611+
copy_lcd_v_bitmap(bm->buf, cell, &src, &dest, bm->stride, cell_width, bm->bgr);
599612
} else render_alpha_mask(bm->buf, cell, &src, &dest, bm->stride, cell_width);
600613
}
601614

0 commit comments

Comments
 (0)