Skip to content

Commit

Permalink
implement RGBA glyphs on X11
Browse files Browse the repository at this point in the history
  • Loading branch information
dk committed Nov 24, 2024
1 parent 8212c29 commit 27f871a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 27 deletions.
6 changes: 3 additions & 3 deletions include/unix/guts.h
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ extern unsigned long *
prima_xft_mapper_query_ranges(PFont font, int * count, unsigned int * flags);

extern Byte*
prima_xft_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance);
prima_xft_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance, int *bpp);

extern Bool
prima_xft_is_font_colored(Handle self);
Expand Down Expand Up @@ -1878,7 +1878,7 @@ extern Bool
prima_fq_set_font( Handle self, PCachedFont kf);

extern Byte*
prima_fq_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance);
prima_fq_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance, int *bpp);

extern int
prima_fq_get_glyph_outline( Handle self, unsigned int index, unsigned int flags, int ** buffer);
Expand Down Expand Up @@ -1941,7 +1941,7 @@ extern int
prima_ft_get_glyph_outline( FT_Face face, FT_UInt ft_index, FT_Int32 ft_flags, int ** buffer);

extern Byte*
prima_ft_get_glyph_bitmap( FT_Face face, FT_UInt index, FT_Int32 flags, PPoint offset, PPoint size, int *advance);
prima_ft_get_glyph_bitmap( FT_Face face, FT_UInt index, FT_Int32 flags, PPoint offset, PPoint size, int *advance, int *bpp);

extern Bool
prima_ft_is_font_colored( FT_Face face);
Expand Down
11 changes: 6 additions & 5 deletions unix/font.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,16 +809,15 @@ apc_font_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoi

#ifdef USE_FONTQUERY
if ( is_opt(optInFontQuery) ) {
if ( X(self)->font) {
return prima_fq_get_glyph_bitmap(self, index, flags, offset, size, advance);
}
if ( X(self)->font)
return prima_fq_get_glyph_bitmap(self, index, flags, offset, size, advance, bpp);
return NULL;
}
#endif

#ifdef USE_XFT
if ( X(self)-> font-> xft)
return prima_xft_get_glyph_bitmap(self, index, flags, offset, size, advance);
return prima_xft_get_glyph_bitmap(self, index, flags, offset, size, advance, bpp);
#endif

return prima_corefont_get_glyph_bitmap(self, index, flags & ggoMonochrome, offset, size, advance);
Expand All @@ -840,7 +839,9 @@ apc_font_is_colored( Handle self)

#ifdef USE_FONTQUERY
if ( is_opt(optInFontQuery) ) {
return false; /* XXX because colored bitmaps are not supported */
Bool ok = prima_ft_is_font_colored(X(self)->font->ft_face);
f->has_colors = ok ? 1 : -1;
return ok;
}
#endif

Expand Down
5 changes: 3 additions & 2 deletions unix/fontquery.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,15 @@ prima_fq_get_glyph_outline( Handle self, unsigned int index, unsigned int flags,
}

Byte*
prima_fq_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance)
prima_fq_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance, int *type)
{
FT_Int32 ft_flags =
FT_LOAD_RENDER |
(( flags & ggoARGB ) ? FT_LOAD_COLOR : 0) |
(( flags & ggoUseHints ) ? 0 : FT_LOAD_NO_HINTING) |
(( flags & ggoMonochrome ) ? FT_LOAD_MONOCHROME : 0)
;
return prima_ft_get_glyph_bitmap(X(self)->font->ft_face, index, ft_flags, offset, size, advance);
return prima_ft_get_glyph_bitmap(X(self)->font->ft_face, index, ft_flags, offset, size, advance, type);
}

unsigned long *
Expand Down
73 changes: 58 additions & 15 deletions unix/freetype.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,17 +240,54 @@ prima_ft_get_glyph_outline( FT_Face face, FT_UInt ft_index, FT_Int32 ft_flags, i
}

Byte*
prima_ft_get_glyph_bitmap( FT_Face face, FT_UInt index, FT_Int32 flags, PPoint offset, PPoint size, int *advance)
prima_ft_get_glyph_bitmap( FT_Face face, FT_UInt index, FT_Int32 flags, PPoint offset, PPoint size, int *advance, int *bpp)
{
Byte *ret = NULL;
FT_Bitmap *b;
int src_stride;
Byte *src;

if ( FT_Load_Glyph (face, index, flags) == 0 ) {
FT_Bitmap *b = &face->glyph->bitmap;
int dst_stride = ((b->width * ((flags & FT_LOAD_MONOCHROME) ? 1 : 8) + 31) / 32) * 4;
int src_stride = abs(b->pitch);
if ( FT_Load_Glyph (face, index, flags) != 0 )
return NULL;

if ( !( b = &face->glyph->bitmap))
return NULL;

src = b->buffer;
src_stride = abs(b->pitch);

#define LINE_SIZE(width,type) (((( width ) * (( type ) & imBPP) + 31) / 32) * 4)
if ( b-> pixel_mode == FT_PIXEL_MODE_BGRA ) {
int y, dst_stride = LINE_SIZE(b->width, 24 ), mask_stride = LINE_SIZE(b->width, 8);
if ( ( ret = malloc( (dst_stride + mask_stride) * b->rows )) != NULL ) {
Byte *dst = ret, *mask = dst + dst_stride * b->rows;
if ( b->pitch > 0 ) {
dst += dst_stride * (b->rows - 1);
dst_stride = -dst_stride;
mask += mask_stride * (b->rows - 1);
mask_stride = -mask_stride;
}

for (
y = 0;
y < b->rows;
y++, dst += dst_stride, mask += mask_stride
) {
register unsigned int n = b->width;
register Byte *d = dst, *m = mask;
while (n--) {
*(d++) = *(src++);
*(d++) = *(src++);
*(d++) = *(src++);
*(m++) = *(src++);
}
}
}
*bpp = 32;
} else {
int dst_stride = LINE_SIZE(b->width, (flags & FT_LOAD_MONOCHROME) ? 1 : 8);
int bytes = (src_stride > dst_stride) ? dst_stride : src_stride;
Byte *src = b->buffer;
if ( b && ( ret = malloc( b->rows * dst_stride ))) {
if (( ret = malloc( b->rows * dst_stride )) != NULL) {
int i;
Byte *dst = ret;
if ( b->pitch > 0 ) {
Expand All @@ -259,17 +296,22 @@ prima_ft_get_glyph_bitmap( FT_Face face, FT_UInt index, FT_Int32 flags, PPoint o
}
for ( i = 0; i < b->rows; i++, src += src_stride, dst += dst_stride)
memcpy( dst, src, bytes);
}
*bpp = (flags & FT_LOAD_MONOCHROME) ? 1 : 8;
}

offset->x = face->glyph->bitmap_left;
offset->y = face->glyph->bitmap_top - b->rows;
size->x = b->width;
size->y = b->rows;
if ( advance ) {
FT_Fixed a = face->glyph->linearHoriAdvance;
*advance = (a >> 16) + (((a & 0xffff) > 0x7fff) ? 1 : 0);
}
if ( ret ) {
offset->x = face->glyph->bitmap_left;
offset->y = face->glyph->bitmap_top - b->rows;
size->x = b->width;
size->y = b->rows;
if ( advance ) {
FT_Fixed a = face->glyph->linearHoriAdvance;
*advance = (a >> 16) + (((a & 0xffff) > 0x7fff) ? 1 : 0);
}
}
#undef LINE_SIZE

return ret;
}

Expand Down Expand Up @@ -392,6 +434,7 @@ prima_ft_is_font_colored( FT_Face face)
FT_Library_Version(ft_library,&a,&b,&c);
if ( a < 2 || ( a == 2 && b < 10 )) /* CPAL/COLR only supported in 2.10 */
return false;

return
(FT_Load_Sfnt_Table(face, TTAG_COLR, 0, NULL, &l1) == 0) &&
(FT_Load_Sfnt_Table(face, TTAG_CPAL, 0, NULL, &l2) == 0)
Expand Down
5 changes: 3 additions & 2 deletions unix/xft.c
Original file line number Diff line number Diff line change
Expand Up @@ -1410,19 +1410,20 @@ prima_xft_get_glyph_outline( Handle self, unsigned int index, unsigned int flags
}

Byte*
prima_xft_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance)
prima_xft_get_glyph_bitmap( Handle self, uint16_t index, unsigned int flags, PPoint offset, PPoint size, int *advance, int *bpp)
{
DEFXX;
Byte *ret;
FT_Face face;
FT_Int32 ft_flags =
FT_LOAD_RENDER |
(( flags & ggoARGB ) ? FT_LOAD_COLOR : 0) |
(( flags & ggoUseHints ) ? 0 : FT_LOAD_NO_HINTING) |
(( flags & ggoMonochrome ) ? FT_LOAD_MONOCHROME : 0)
;
if ( !( face = XftLockFace( XX->font->xft)))
return NULL;
ret = prima_ft_get_glyph_bitmap(face, index, ft_flags, offset, size, advance);
ret = prima_ft_get_glyph_bitmap(face, index, ft_flags, offset, size, advance, bpp);
XftUnlockFace(XX->font->xft);
return ret;
}
Expand Down

0 comments on commit 27f871a

Please sign in to comment.