0ad/source/tools/fontbuilder2/font_loader.py
Dunedan 0ea6d32fa5
Enable various ruff rules
This commit enables a bunch of unrelated ruff rules, which only require
minimal changes to the code base to enable them.

The rules enabled by this commit are:

- check the use of datetime objects without timezone (DTZ005)
- check the performance of try-except in loops (PERF203)
- check the number of function arguments (PLR0913)
- check for mutable class defaults (RUF012)
- check for the use of secure hashing algorithms (S324)
- check for raising base exceptions (TRY002)
- check for raising other exceptions where TypeErrors should be raised
  (TRY004)
2024-09-21 20:54:30 +02:00

78 lines
2.4 KiB
Python

# Adapted from http://cairographics.org/freetypepython/
# ruff: noqa: TRY002
import ctypes
import sys
from typing import ClassVar
import cairo
CAIRO_STATUS_SUCCESS = 0
FT_Err_Ok = 0
FT_LOAD_DEFAULT = 0x0
FT_LOAD_NO_HINTING = 0x2
FT_LOAD_FORCE_AUTOHINT = 0x20
FT_LOAD_NO_AUTOHINT = 0x8000
# find required libraries (platform specific)
if sys.platform == "win32":
ft_lib = "freetype6.dll"
lc_lib = "libcairo-2.dll"
else:
ft_lib = "libfreetype.so.6"
lc_lib = "libcairo.so.2"
_freetype_so = ctypes.CDLL(ft_lib)
_cairo_so = ctypes.CDLL(lc_lib)
_cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p
_cairo_so.cairo_ft_font_face_create_for_ft_face.argtypes = [ctypes.c_void_p, ctypes.c_int]
_cairo_so.cairo_set_font_face.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
_cairo_so.cairo_font_face_status.argtypes = [ctypes.c_void_p]
_cairo_so.cairo_status.argtypes = [ctypes.c_void_p]
# initialize freetype
_ft_lib = ctypes.c_void_p()
if FT_Err_Ok != _freetype_so.FT_Init_FreeType(ctypes.byref(_ft_lib)):
raise Exception("Error initialising FreeType library.")
_surface = cairo.ImageSurface(cairo.FORMAT_A8, 0, 0)
class PycairoContext(ctypes.Structure):
_fields_: ClassVar = [
("PyObject_HEAD", ctypes.c_byte * object.__basicsize__),
("ctx", ctypes.c_void_p),
("base", ctypes.c_void_p),
]
def create_cairo_font_face_for_file(filename, faceindex=0, loadoptions=0):
# create freetype face
ft_face = ctypes.c_void_p()
cairo_ctx = cairo.Context(_surface)
cairo_t = PycairoContext.from_address(id(cairo_ctx)).ctx
if FT_Err_Ok != _freetype_so.FT_New_Face(
_ft_lib, filename.encode("ascii"), faceindex, ctypes.byref(ft_face)
):
raise Exception("Error creating FreeType font face for " + filename)
# create cairo font face for freetype face
cr_face = _cairo_so.cairo_ft_font_face_create_for_ft_face(ft_face, loadoptions)
if _cairo_so.cairo_font_face_status(cr_face) != CAIRO_STATUS_SUCCESS:
raise Exception("Error creating cairo font face for " + filename)
_cairo_so.cairo_set_font_face(cairo_t, cr_face)
if _cairo_so.cairo_status(cairo_t) != CAIRO_STATUS_SUCCESS:
raise Exception("Error creating cairo font face for " + filename)
face = cairo_ctx.get_font_face()
def indexes(char):
return _freetype_so.FT_Get_Char_Index(ft_face, ord(char))
return (face, indexes)