Skip to content

Commit 97aeea6

Browse files
authored
Merge pull request #3574 from Starbuck5/sdl3_freetype
Port freetype to SDL3
2 parents 83d395f + 6c2e05d commit 97aeea6

File tree

6 files changed

+98
-66
lines changed

6 files changed

+98
-66
lines changed

src_c/freetype/ft_pixel.h

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,37 @@
2222

2323
#include "../surface.h"
2424

25-
#define GET_RGB_VALS(pixel, fmt, r, g, b, a) \
26-
(r) = ((pixel) & (fmt)->Rmask) >> (fmt)->Rshift; \
27-
(r) = ((r) << (fmt)->Rloss) + ((r) >> (8 - ((fmt)->Rloss << 1))); \
28-
(g) = ((pixel) & (fmt)->Gmask) >> (fmt)->Gshift; \
29-
(g) = ((g) << (fmt)->Gloss) + ((g) >> (8 - ((fmt)->Gloss << 1))); \
30-
(b) = ((pixel) & (fmt)->Bmask) >> (fmt)->Bshift; \
31-
(b) = ((b) << (fmt)->Bloss) + ((b) >> (8 - ((fmt)->Bloss << 1))); \
32-
if ((fmt)->Amask) { \
33-
(a) = ((pixel) & (fmt)->Amask) >> (fmt)->Ashift; \
34-
(a) = ((a) << (fmt)->Aloss) + ((a) >> (8 - ((fmt)->Aloss << 1))); \
35-
} \
36-
else { \
37-
(a) = 255; \
25+
#define GET_RGB_VALS(pixel, fmt, r, g, b, a) \
26+
(r) = ((pixel) & (fmt)->Rmask) >> (fmt)->Rshift; \
27+
(r) = ((r) << PG_FORMAT_R_LOSS(fmt)) + \
28+
((r) >> (8 - (PG_FORMAT_R_LOSS(fmt) << 1))); \
29+
(g) = ((pixel) & (fmt)->Gmask) >> (fmt)->Gshift; \
30+
(g) = ((g) << PG_FORMAT_G_LOSS(fmt)) + \
31+
((g) >> (8 - (PG_FORMAT_G_LOSS(fmt) << 1))); \
32+
(b) = ((pixel) & (fmt)->Bmask) >> (fmt)->Bshift; \
33+
(b) = ((b) << PG_FORMAT_B_LOSS(fmt)) + \
34+
((b) >> (8 - (PG_FORMAT_B_LOSS(fmt) << 1))); \
35+
if ((fmt)->Amask) { \
36+
(a) = ((pixel) & (fmt)->Amask) >> (fmt)->Ashift; \
37+
(a) = ((a) << PG_FORMAT_A_LOSS(fmt)) + \
38+
((a) >> (8 - (PG_FORMAT_A_LOSS(fmt) << 1))); \
39+
} \
40+
else { \
41+
(a) = 255; \
3842
}
3943

40-
#define GET_PALETTE_VALS(pixel, fmt, sr, sg, sb, sa) \
41-
(sr) = (fmt)->palette->colors[(Uint8)(pixel)].r; \
42-
(sg) = (fmt)->palette->colors[(Uint8)(pixel)].g; \
43-
(sb) = (fmt)->palette->colors[(Uint8)(pixel)].b; \
44+
#define GET_PALETTE_VALS(pixel, palette, sr, sg, sb, sa) \
45+
(sr) = palette->colors[(Uint8)(pixel)].r; \
46+
(sg) = palette->colors[(Uint8)(pixel)].g; \
47+
(sb) = palette->colors[(Uint8)(pixel)].b; \
4448
(sa) = 255;
4549

46-
#define GET_PIXEL_VALS(pixel, fmt, r, g, b, a) \
47-
if (!(fmt)->palette) { \
48-
GET_RGB_VALS(pixel, fmt, r, g, b, a); \
49-
} \
50-
else { \
51-
GET_PALETTE_VALS(pixel, fmt, r, g, b, a); \
50+
#define GET_PIXEL_VALS(pixel, fmt, palette, r, g, b, a) \
51+
if (!palette) { \
52+
GET_RGB_VALS(pixel, fmt, r, g, b, a); \
53+
} \
54+
else { \
55+
GET_PALETTE_VALS(pixel, palette, r, g, b, a); \
5256
}
5357

5458
#if SDL_BYTEORDER == SDL_LIL_ENDIAN

src_c/freetype/ft_render.c

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,16 @@ _PGFT_Render_ExistingSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
348348
font_surf.width = surface->w;
349349
font_surf.height = surface->h;
350350
font_surf.pitch = surface->pitch;
351-
font_surf.format = surface->format;
352351
font_surf.render_gray = __SDLrenderFuncs[PG_SURF_BytesPerPixel(surface)];
353352
font_surf.render_mono = __MONOrenderFuncs[PG_SURF_BytesPerPixel(surface)];
354353
font_surf.fill = __RGBfillFuncs[PG_SURF_BytesPerPixel(surface)];
355354

355+
if (!PG_GetSurfaceDetails(surface, &font_surf.format,
356+
&font_surf.palette)) {
357+
PyErr_SetString(pgExc_SDLError, SDL_GetError());
358+
return -1;
359+
}
360+
356361
/*
357362
* if bg color exists, paint background
358363
*/
@@ -361,8 +366,9 @@ _PGFT_Render_ExistingSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
361366
SDL_Rect bg_fill;
362367
FT_UInt32 fillcolor;
363368

364-
fillcolor = SDL_MapRGBA(surface->format, bgcolor->r, bgcolor->g,
365-
bgcolor->b, bgcolor->a);
369+
fillcolor =
370+
PG_MapRGBA(font_surf.format, font_surf.palette, bgcolor->r,
371+
bgcolor->g, bgcolor->b, bgcolor->a);
366372

367373
bg_fill.x = (FT_Int16)x;
368374
bg_fill.y = (FT_Int16)y;
@@ -404,7 +410,6 @@ _PGFT_Render_NewSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
404410
SDL_Surface *surface = 0;
405411
int bits_per_pixel =
406412
(bgcolor || mode->render_flags & FT_RFLAG_ANTIALIAS) ? 32 : 8;
407-
Uint32 pixelformat;
408413

409414
FontSurface font_surf;
410415
Layout *font_text;
@@ -433,17 +438,26 @@ _PGFT_Render_NewSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
433438
}
434439

435440
if (bits_per_pixel == 8) {
436-
pixelformat = SDL_PIXELFORMAT_INDEX8;
441+
surface = PG_CreateSurface(width, height, SDL_PIXELFORMAT_INDEX8);
442+
#if SDL_VERSION_ATLEAST(3, 0, 0)
443+
// We need to explicitly create palettes in SDL3
444+
SDL_CreateSurfacePalette(surface);
445+
#endif
437446
}
438447
else {
439-
pixelformat = SDL_PIXELFORMAT_RGBA32;
448+
surface = PG_CreateSurface(width, height, SDL_PIXELFORMAT_RGBA32);
440449
}
441-
surface = PG_CreateSurface(width, height, pixelformat);
450+
442451
if (!surface) {
443452
PyErr_SetString(pgExc_SDLError, SDL_GetError());
444453
return 0;
445454
}
446455

456+
if (!PG_GetSurfaceDetails(surface, &font_surf.format,
457+
&font_surf.palette)) {
458+
return RAISE(pgExc_SDLError, SDL_GetError());
459+
}
460+
447461
if (SDL_MUSTLOCK(surface)) {
448462
if (!PG_LockSurface(surface)) {
449463
PyErr_SetString(pgExc_SDLError, SDL_GetError());
@@ -457,7 +471,7 @@ _PGFT_Render_NewSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
457471
font_surf.width = surface->w;
458472
font_surf.height = surface->h;
459473
font_surf.pitch = surface->pitch;
460-
font_surf.format = surface->format;
474+
461475
if (bits_per_pixel == 32) {
462476
FT_UInt32 fillcolor;
463477

@@ -468,20 +482,20 @@ _PGFT_Render_NewSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
468482
* Fill our texture with the required bg color
469483
*/
470484
if (bgcolor) {
471-
fillcolor = SDL_MapRGBA(surface->format, bgcolor->r, bgcolor->g,
472-
bgcolor->b, bgcolor->a);
485+
fillcolor =
486+
PG_MapRGBA(font_surf.format, font_surf.palette, bgcolor->r,
487+
bgcolor->g, bgcolor->b, bgcolor->a);
473488
}
474489
else {
475-
fillcolor =
476-
SDL_MapRGBA(surface->format, 0, 0, 0, SDL_ALPHA_TRANSPARENT);
490+
fillcolor = PG_MapRGBA(font_surf.format, font_surf.palette, 0, 0,
491+
0, SDL_ALPHA_TRANSPARENT);
477492
}
478493
SDL_FillRect(surface, 0, fillcolor);
479494
}
480495
else {
481-
SDL_Palette *palette = surface->format->palette;
482496
SDL_Color colors[2];
483497

484-
if (!palette) {
498+
if (!font_surf.palette) {
485499
SDL_FreeSurface(surface);
486500
PyErr_NoMemory();
487501
return 0;
@@ -494,7 +508,7 @@ _PGFT_Render_NewSurface(FreeTypeInstance *ft, pgFontObject *fontobj,
494508
colors[0].g = ~colors[1].g;
495509
colors[0].b = ~colors[1].b;
496510
colors[0].a = SDL_ALPHA_OPAQUE;
497-
if (!PG_SetPaletteColors(palette, colors, 0, 2)) {
511+
if (!PG_SetPaletteColors(font_surf.palette, colors, 0, 2)) {
498512
PyErr_Format(PyExc_SystemError,
499513
"Pygame bug in _PGFT_Render_NewSurface: %.200s",
500514
SDL_GetError());
@@ -598,6 +612,7 @@ _PGFT_Render_PixelArray(FreeTypeInstance *ft, pgFontObject *fontobj,
598612
surf.height = height;
599613
surf.pitch = (int)surf.width;
600614
surf.format = 0;
615+
surf.palette = NULL;
601616
surf.render_gray = __render_glyph_GRAY1;
602617
surf.render_mono = __render_glyph_MONO_as_GRAY1;
603618
surf.fill = __fill_glyph_GRAY1;
@@ -628,7 +643,6 @@ _PGFT_Render_Array(FreeTypeInstance *ft, pgFontObject *fontobj,
628643
FT_Fixed underline_size;
629644

630645
FontSurface font_surf;
631-
SDL_PixelFormat format;
632646
Layout *font_text;
633647

634648
/* Get target buffer */
@@ -696,8 +710,11 @@ _PGFT_Render_Array(FreeTypeInstance *ft, pgFontObject *fontobj,
696710
* Setup target surface struct
697711
*/
698712
#if SDL_VERSION_ATLEAST(3, 0, 0)
713+
// Only BPP and Ashift are needed by functions called here
714+
SDL_PixelFormatDetails format;
699715
format.bytes_per_pixel = itemsize;
700716
#else
717+
SDL_PixelFormat format;
701718
format.BytesPerPixel = itemsize;
702719
#endif
703720
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
@@ -711,6 +728,7 @@ _PGFT_Render_Array(FreeTypeInstance *ft, pgFontObject *fontobj,
711728
font_surf.item_stride = (unsigned)view_p->strides[0];
712729
font_surf.pitch = (unsigned)view_p->strides[1];
713730
font_surf.format = &format;
731+
font_surf.palette = NULL;
714732
font_surf.render_gray = __render_glyph_INT;
715733
font_surf.render_mono = __render_glyph_MONO_as_INT;
716734
font_surf.fill = __fill_glyph_INT;

src_c/freetype/ft_render_cb.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ __render_glyph_INT(int x, int y, FontSurface *surface, const FT_Bitmap *bitmap,
220220
{
221221
FT_Byte *dst = ((FT_Byte *)surface->buffer + x * surface->item_stride +
222222
y * surface->pitch);
223-
int item_size = PG_SURF_BytesPerPixel(surface);
223+
int item_size = PG_FORMAT_BytesPerPixel(surface->format);
224224
int item_stride = surface->item_stride;
225225
FT_Byte *dst_cpy;
226226

@@ -301,7 +301,7 @@ __render_glyph_MONO_as_INT(int x, int y, FontSurface *surface,
301301

302302
int i, j, shift;
303303
int item_stride = surface->item_stride;
304-
int item_size = PG_SURF_BytesPerPixel(surface);
304+
int item_size = PG_FORMAT_BytesPerPixel(surface->format);
305305
unsigned char *src;
306306
unsigned char *dst;
307307
unsigned char *src_cpy;
@@ -380,7 +380,7 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
380380
{
381381
int i, j;
382382
FT_Byte *dst;
383-
int itemsize = PG_SURF_BytesPerPixel(surface);
383+
int itemsize = PG_FORMAT_BytesPerPixel(surface->format);
384384
int item_stride = surface->item_stride;
385385
int byteoffset = surface->format->Ashift / 8;
386386
FT_Byte *dst_cpy;
@@ -544,7 +544,7 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
544544
POINTER_ASSERT(_dst) \
545545
\
546546
if (_bpp == 1) { \
547-
GET_PALETTE_VALS(pixel, surface->format, bgR, bgG, bgB, \
547+
GET_PALETTE_VALS(pixel, surface->palette, bgR, bgG, bgB, \
548548
bgA); \
549549
} \
550550
else { \
@@ -575,7 +575,7 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
575575
POINTER_ASSERT(_dst) \
576576
\
577577
if (_bpp == 1) { \
578-
GET_PALETTE_VALS(pixel, surface->format, bgR, bgG, bgB, \
578+
GET_PALETTE_VALS(pixel, surface->palette, bgR, bgG, bgB, \
579579
bgA); \
580580
} \
581581
else { \
@@ -607,7 +607,7 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
607607
POINTER_ASSERT(_dst) \
608608
\
609609
if (_bpp == 1) { \
610-
GET_PALETTE_VALS(pixel, surface->format, bgR, bgG, bgB, \
610+
GET_PALETTE_VALS(pixel, surface->palette, bgR, bgG, bgB, \
611611
bgA); \
612612
} \
613613
else { \
@@ -666,8 +666,9 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
666666
dst = (unsigned char *)surface->buffer + (rx * _bpp) + \
667667
(ry * surface->pitch); \
668668
\
669-
full_color = SDL_MapRGBA(surface->format, (FT_Byte)color->r, \
670-
(FT_Byte)color->g, (FT_Byte)color->b, 255); \
669+
full_color = \
670+
PG_MapRGBA(surface->format, surface->palette, (FT_Byte)color->r, \
671+
(FT_Byte)color->g, (FT_Byte)color->b, 255); \
671672
\
672673
shift = off_x & 7; \
673674
(void)full_color; \
@@ -679,7 +680,7 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
679680
FT_UInt32 pixel = (FT_UInt32)_getp; \
680681
\
681682
if (_bpp == 1) { \
682-
GET_PALETTE_VALS(pixel, surface->format, bgR, bgG, bgB, \
683+
GET_PALETTE_VALS(pixel, surface->palette, bgR, bgG, bgB, \
683684
bgA); \
684685
} \
685686
else { \
@@ -743,7 +744,7 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
743744
FT_UInt32 pixel = (FT_UInt32)_getp; \
744745
\
745746
if (_bpp == 1) { \
746-
GET_PALETTE_VALS(pixel, surface->format, bgR, bgG, \
747+
GET_PALETTE_VALS(pixel, surface->palette, bgR, bgG, \
747748
bgB, bgA); \
748749
} \
749750
else { \
@@ -765,9 +766,10 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
765766

766767
/* These macros removes a gcc unused variable warning for __render_glyph_RGB3
767768
*/
768-
#define _DECLARE_full_color(s, c) \
769-
const FT_UInt32 full_color = SDL_MapRGBA( \
770-
(s)->format, (FT_Byte)(c)->r, (FT_Byte)(c)->g, (FT_Byte)(c)->b, 255);
769+
#define _DECLARE_full_color(s, c) \
770+
const FT_UInt32 full_color = \
771+
PG_MapRGBA((s)->format, (s)->palette, (FT_Byte)(c)->r, \
772+
(FT_Byte)(c)->g, (FT_Byte)(c)->b, 255);
771773
#define _DECLARE_full_color1(s, c) _DECLARE_full_color(s, c)
772774
#define _DECLARE_full_color2(s, c) _DECLARE_full_color(s, c)
773775
#define _DECLARE_full_color3(s, c)
@@ -780,17 +782,20 @@ __fill_glyph_INT(FT_Fixed x, FT_Fixed y, FT_Fixed w, FT_Fixed h,
780782

781783
#define _SET_PIXEL(T) *(T *)_dst = (T)full_color;
782784

783-
#define _BLEND_PIXEL(T) \
784-
*((T *)_dst) = \
785-
(T)(((bgR >> surface->format->Rloss) << surface->format->Rshift) | \
786-
((bgG >> surface->format->Gloss) << surface->format->Gshift) | \
787-
((bgB >> surface->format->Bloss) << surface->format->Bshift) | \
788-
((bgA >> surface->format->Aloss) << surface->format->Ashift & \
789-
surface->format->Amask))
790-
791-
#define _BLEND_PIXEL_GENERIC(T) \
792-
*(T *)_dst = (T)(SDL_MapRGB(surface->format, (FT_Byte)bgR, (FT_Byte)bgG, \
793-
(FT_Byte)bgB))
785+
#define _BLEND_PIXEL(T) \
786+
*((T *)_dst) = (T)(((bgR >> PG_FORMAT_R_LOSS(surface->format)) \
787+
<< surface->format->Rshift) | \
788+
((bgG >> PG_FORMAT_G_LOSS(surface->format)) \
789+
<< surface->format->Gshift) | \
790+
((bgB >> PG_FORMAT_B_LOSS(surface->format)) \
791+
<< surface->format->Bshift) | \
792+
((bgA >> PG_FORMAT_A_LOSS(surface->format)) \
793+
<< surface->format->Ashift & \
794+
surface->format->Amask))
795+
796+
#define _BLEND_PIXEL_GENERIC(T) \
797+
*(T *)_dst = (T)(PG_MapRGB(surface->format, surface->palette, \
798+
(FT_Byte)bgR, (FT_Byte)bgG, (FT_Byte)bgB))
794799

795800
#define _GET_PIXEL(T) (*((T *)_dst))
796801

src_c/freetype/ft_wrap.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,11 @@ RWops_read(FT_Stream stream, unsigned long offset, unsigned char *buffer,
479479
return 0;
480480
}
481481

482+
#if SDL_VERSION_ATLEAST(3, 0, 0)
483+
return (unsigned long)SDL_ReadIO(src, buffer, count);
484+
#else
482485
return (unsigned long)SDL_RWread(src, buffer, 1, (int)count);
486+
#endif
483487
}
484488

485489
int

src_c/freetype/ft_wrap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ typedef struct fontsurface_ {
200200
int item_stride;
201201
int pitch;
202202

203-
SDL_PixelFormat *format;
203+
PG_PixelFormat *format;
204+
SDL_Palette *palette;
204205

205206
FontRenderPtr render_gray;
206207
FontRenderPtr render_mono;

src_c/meson.build

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ if sdl_mixer_dep.found()
421421
)
422422
endif
423423

424+
endif
425+
424426
if freetype_dep.found()
425427
_freetype = py.extension_module(
426428
'_freetype',
@@ -440,8 +442,6 @@ if freetype_dep.found()
440442
)
441443
endif
442444

443-
endif
444-
445445
if portmidi_dep.found()
446446
pypm = py.extension_module(
447447
'pypm',

0 commit comments

Comments
 (0)