@@ -375,16 +375,19 @@ trim_borders(ProcessedBitmap *ans, size_t extra) {
375375static inline void
376376populate_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
390393static 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+
564578static inline void
565579place_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