Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm only] freetype 2 init and some cleanup #1967

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 47 additions & 23 deletions src_c/_freetype.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@
#define MODULE_NAME "_freetype"
#define FONT_TYPE_NAME "Font"

#define DEFAULT_FONT_NAME "freesans"
#define DEFAULT_FONT_FILE "freesansbold.ttf"
#define PKGDATA_MODULE_NAME "pygame.pkgdata"
#define RESOURCE_FUNC_NAME "getResource"

/*
* FreeType module declarations
*/

PyObject *_freetypemodule = NULL;

static const Scale_t FACE_SIZE_NONE = {0, 0};

static int
Expand Down Expand Up @@ -208,10 +216,6 @@ free_string(PGFT_String *);
_var = PyObject_IsTrue(_pyobj); \
}

#define DEFAULT_FONT_NAME "freesansbold.ttf"
#define PKGDATA_MODULE_NAME "pygame.pkgdata"
#define RESOURCE_FUNC_NAME "getResource"

static PyObject *
load_font_res(const char *filename)
{
Expand Down Expand Up @@ -692,7 +696,11 @@ _ftfont_init(pgFontObject *self, PyObject *args, PyObject *kwds)
SDL_RWops *source;

FreeTypeInstance *ft;
#if defined(__EMSCRIPTEN__)
ft = FREETYPE_MOD_STATE(_freetypemodule)->freetype;
#else
ASSERT_GRAB_FREETYPE(ft, -1);
#endif

if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&lIi", kwlist, &file,
obj_to_scale, (void *)&face_size,
Expand Down Expand Up @@ -726,7 +734,7 @@ _ftfont_init(pgFontObject *self, PyObject *args, PyObject *kwds)
self->resolution = FREETYPE_STATE->resolution;
}
if (file == Py_None) {
file = load_font_res(DEFAULT_FONT_NAME);
file = load_font_res(DEFAULT_FONT_FILE);

if (!file) {
PyErr_SetString(PyExc_RuntimeError, "Failed to find default font");
Expand Down Expand Up @@ -2040,6 +2048,14 @@ _ft_get_error(PyObject *self, PyObject *_null)
Py_RETURN_NONE;
}

#if defined(__EMSCRIPTEN__)
static PyObject *
_ft_get_version(PyObject *self, PyObject *args, PyObject *kwargs)
{
return Py_BuildValue("iii", FREETYPE_MAJOR, FREETYPE_MINOR,
FREETYPE_PATCH);
}
#else
static PyObject *
_ft_get_version(PyObject *self, PyObject *args, PyObject *kwargs)
{
Expand Down Expand Up @@ -2086,6 +2102,7 @@ _ft_get_version(PyObject *self, PyObject *args, PyObject *kwargs)
FREETYPE_PATCH);
}
}
#endif // defined(__EMSCRIPTEN__)

static PyObject *
_ft_get_cache_size(PyObject *self, PyObject *_null)
Expand Down Expand Up @@ -2125,7 +2142,7 @@ _ft_get_init(PyObject *self, PyObject *_null)
static PyObject *
_ft_get_default_font(PyObject *self, PyObject *_null)
{
return PyUnicode_FromString(DEFAULT_FONT_NAME);
return PyUnicode_FromString(DEFAULT_FONT_FILE);
}

static int
Expand All @@ -2148,13 +2165,13 @@ _ft_clear(PyObject *mod)
* FREETYPE MODULE DECLARATION
****************************************************/
#ifndef PYPY_VERSION
struct PyModuleDef _freetypemodule = {
struct PyModuleDef _freetypemoduledef = {
PyModuleDef_HEAD_INIT, MODULE_NAME, DOC_FREETYPE,
sizeof(_FreeTypeState), _ft_methods, 0,
_ft_traverse, _ft_clear, 0};
#else /* PYPY_VERSION */
_FreeTypeState _modstate;
struct PyModuleDef _freetypemodule = {
struct PyModuleDef _freetypemoduledef = {
PyModuleDef_HEAD_INIT,
MODULE_NAME,
DOC_FREETYPE,
Expand All @@ -2168,7 +2185,7 @@ struct PyModuleDef _freetypemodule = {

MODINIT_DEFINE(_freetype)
{
PyObject *module, *apiobj;
PyObject *apiobj;
static void *c_api[PYGAMEAPI_FREETYPE_NUMSLOTS];

import_pygame_base();
Expand Down Expand Up @@ -2201,27 +2218,34 @@ MODINIT_DEFINE(_freetype)
return NULL;
}

module = PyModule_Create(&_freetypemodule);
_freetypemodule = PyModule_Create(&_freetypemoduledef);

if (!module) {
if (!_freetypemodule) {
return NULL;
}

FREETYPE_MOD_STATE(module)->freetype = 0;
FREETYPE_MOD_STATE(module)->cache_size = 0;
FREETYPE_MOD_STATE(module)->resolution = PGFT_DEFAULT_RESOLUTION;
#if defined(__EMSCRIPTEN__)
//_PGFT_Init(&(FREETYPE_MOD_STATE(_freetypemodule)->freetype), 0);
#pragma message "NO _PGFT_Init"
FREETYPE_MOD_STATE(_freetypemodule)->freetype = 0;
#else
FREETYPE_MOD_STATE(_freetypemodule)->freetype = 0;
#endif
FREETYPE_MOD_STATE(_freetypemodule)->cache_size = 0;
FREETYPE_MOD_STATE(_freetypemodule)->resolution = PGFT_DEFAULT_RESOLUTION;

Py_INCREF(&pgFont_Type);
if (PyModule_AddObject(module, FONT_TYPE_NAME, (PyObject *)&pgFont_Type)) {
if (PyModule_AddObject(_freetypemodule, FONT_TYPE_NAME,
(PyObject *)&pgFont_Type)) {
Py_DECREF(&pgFont_Type);
Py_DECREF(module);
Py_DECREF(_freetypemodule);
return NULL;
}

#define DEC_CONST(x) \
if (PyModule_AddIntConstant(module, #x, (int)FT_##x)) { \
Py_DECREF(module); \
return NULL; \
#define DEC_CONST(x) \
if (PyModule_AddIntConstant(_freetypemodule, #x, (int)FT_##x)) { \
Py_DECREF(_freetypemodule); \
return NULL; \
}

DEC_CONST(STYLE_NORMAL);
Expand All @@ -2244,11 +2268,11 @@ MODINIT_DEFINE(_freetype)
c_api[1] = &pgFont_New;

apiobj = encapsulate_api(c_api, "freetype");
if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj)) {
if (PyModule_AddObject(_freetypemodule, PYGAMEAPI_LOCAL_ENTRY, apiobj)) {
Py_XDECREF(apiobj);
Py_DECREF(module);
Py_DECREF(_freetypemodule);
return NULL;
}

return module;
return _freetypemodule;
}
5 changes: 3 additions & 2 deletions src_c/freetype/ft_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,10 @@ typedef struct {
} _FreeTypeState;

#if !defined(PYPY_VERSION)
extern struct PyModuleDef _freetypemodule;
extern struct PyModuleDef _freetypemoduledef;
#define FREETYPE_MOD_STATE(mod) ((_FreeTypeState *)PyModule_GetState(mod))
#define FREETYPE_STATE FREETYPE_MOD_STATE(PyState_FindModule(&_freetypemodule))
#define FREETYPE_STATE \
FREETYPE_MOD_STATE(PyState_FindModule(&_freetypemoduledef))
#else /* defined(PYPY_VERSION) */
extern _FreeTypeState _modstate;
#define FREETYPE_MOD_STATE(mod) (&_modstate)
Expand Down
2 changes: 1 addition & 1 deletion src_py/freetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@


def SysFont(name, size, bold=False, italic=False, constructor=None):
"""pygame.ftfont.SysFont(name, size, bold=False, italic=False, constructor=None) -> Font
"""pygame.freetype.SysFont(name, size, bold=False, italic=False, constructor=None) -> Font
Create a pygame Font from system font resources.

This will search the system fonts for the given font
Expand Down
32 changes: 29 additions & 3 deletions src_py/sysfont.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,40 @@ def initsysfonts_darwin():
return fonts


# read the fonts on unix
# read the fonts on posix/unix
def initsysfonts_unix(path="fc-list"):
"""use the fc-list from fontconfig to get a list of fonts"""
"""if not embedded, use the fc-list from fontconfig to get a list of fonts"""
fonts = {}

if sys.platform == "emscripten":
# these are embedded and cannot get os to list fonts a simple way.
if hasattr(sys, "getandroidapilevel") or sys.platform == "emscripten":
from pathlib import Path

# default font
import importlib.resources
import pygame

entry = importlib.resources.files(pygame) / "freesansbold.ttf"
_parse_font_entry_unix(f"{entry}: FreeSans:style=Bold", fonts)

# cache in search order main script folder, then /tmp
main = __import__("__main__")
if hasattr(main, "__file__"):
fc_cache = Path(main.__file__).parent / "fc_cache"
else:
fc_cache = Path(__import__("tempfile").gettempdir()) / "fc_cache"

if fc_cache.is_file():
with open(fc_cache, "rb") as file:
for entry in file.read().decode("utf-8").splitlines():
_parse_font_entry_unix(entry, fonts)
else:
warnings.warn(f"no fc_cache font cache file at {fc_cache}")

return fonts

# fallback to os support

try:
proc = subprocess.run(
[path, ":", "file", "family", "style"],
Expand Down