Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1e3d970
nullptr check within __add_number
Jul 18, 2026
c67daf1
Use PyErr_GetRaisedException and PyErr_SetRaisedException when using …
Jul 18, 2026
0249364
Silly semicolon omitted
Jul 18, 2026
dc3e4a3
Narrow base class of exception that can be thrown in PyFT2Font_init
Jul 18, 2026
eae6623
Space
Jul 18, 2026
f23f94f
Revert "Narrow base class of exception that can be thrown in PyFT2Fon…
Jul 18, 2026
a2de20c
Ranged-for for iterating family names within ft_glyph_warn
Jul 18, 2026
1258020
Try nullptr check
Jul 18, 2026
7ed13e8
Ranged-for fix
Jul 18, 2026
367880b
Remove old close_file_callback implementation
clin1234 Jul 19, 2026
d8e7003
Fix comma placement in family names output
clin1234 Jul 19, 2026
e9d7bba
Fix condition to check last family name
clin1234 Jul 19, 2026
72243c8
Optimize family names separator check
clin1234 Jul 19, 2026
d175439
Build wheels for 3.15
Jul 18, 2026
73bde29
Check for possible overflow when constructing FT2Image objects
Jul 19, 2026
da4daed
Bump minimum pybind11 to 3.0.0
Jul 19, 2026
a6c9459
Revert "Build wheels for 3.15"
Jul 19, 2026
24716c0
Use py::classh and py::native_enum
Jul 19, 2026
f526dcc
Actually migrate to py::native_enum
Jul 19, 2026
040df20
Use THROW_FT_ERROR in ft2font.cpp
Jul 19, 2026
1a19b13
Back to raw ptrs for now
Jul 19, 2026
26e8425
Maybe unique_ptr for PyFT2Font_init?
Jul 19, 2026
27e27d9
Unique_ptr for PyFT2Font_load_* ?
clin1234 Jul 19, 2026
7238e6a
Mark QhullInfo explicitly as not copyable from another QhullInfo
clin1234 Jul 19, 2026
a17a9ef
NULL -> nullptr
clin1234 Jul 19, 2026
d37ad61
Restrict constexpr to fewer functions
clin1234 Jul 19, 2026
5eba750
Default args in PathIterator::set
clin1234 Jul 19, 2026
1230495
Revert "Use py::classh and py::native_enum"
clin1234 Jul 20, 2026
5f9e1a7
Revert "Actually migrate to py::native_enum"
clin1234 Jul 20, 2026
c713f7e
Partly revert unique_ptr
clin1234 Jul 20, 2026
707bbc9
Initialize code to 0 in constexpr functions
clin1234 Jul 21, 2026
acef2ea
Use [[maybe_unused]]
clin1234 Jul 21, 2026
0d0d977
Define copy assign,ent operator for PathIterator
clin1234 Jul 21, 2026
d446b0c
Set delta and shift to 0 in FT_Outline_Funcs struct
clin1234 Jul 21, 2026
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
2 changes: 1 addition & 1 deletion src/_backend_agg.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ class span_conv_alpha
void prepare()
{
}
void generate(color_type *span, int x, int y, unsigned len) const
void generate(color_type *span, [[maybe_unused]] int x, [[maybe_unused]] int y, unsigned len) const
{
do {
span->a = (agg::int8u)((double)span->a * m_alpha);
Expand Down
2 changes: 1 addition & 1 deletion src/_c_internal_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static py::object
mpl_GetCurrentProcessExplicitAppUserModelID(void)
{
#ifdef _WIN32
wchar_t* appid = NULL;
wchar_t* appid = nullptr;
HRESULT hr = GetCurrentProcessExplicitAppUserModelID(&appid);
if (FAILED(hr)) {
PyErr_SetFromWindowsErr(hr);
Expand Down
2 changes: 1 addition & 1 deletion src/_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace p11x {
auto ival = PyLong_AsLong(tmp); \
value = decltype(value)(ival); \
Py_DECREF(tmp); \
return !(ival == -1 && PyErr_Occurred()); \
return !(ival == -1 && PyErr_Occurred() != nullptr); \
} else { \
return false; \
} \
Expand Down
8 changes: 8 additions & 0 deletions src/_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,14 @@ void __add_number(double val, char format_code, int precision,
{
char *str = PyOS_double_to_string(
val, format_code, precision, Py_DTSF_ADD_DOT_0, nullptr);
if (str == nullptr) {
const char* template_msg = "Cannot call PyOS_double_to_string within %s "
"with the following arguments: val=%f, format_code=%c, precision=%d";
int sz = std::snprintf(nullptr, 0, template_msg, __func__, val, format_code, precision);
std::vector<char> buf(sz + 1); // note +1 for null terminator
std::sprintf(buf.data(), template_msg, __func__, val, format_code, precision); // certain to fit
throw std::invalid_argument(buf.data());
}
// Delete trailing zeros and decimal point
char *c = str + strlen(str) - 1; // Start at last character.
// Rewind through all the zeros and, if present, the trailing decimal
Expand Down
5 changes: 5 additions & 0 deletions src/_qhull_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ class QhullInfo {
}
}

QhullInfo(QhullInfo& other) = delete;
QhullInfo(const QhullInfo& other) = delete;
QhullInfo& operator=(QhullInfo& other) = delete;
QhullInfo& operator=(const QhullInfo& other) = delete;

private:
FILE* error_file;
qhT* qh;
Expand Down
4 changes: 2 additions & 2 deletions src/_tkagg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ using namespace pybind11::literals;
* also.
*/
#define WIN32_DLL
static inline PyObject *PyErr_SetFromWindowsErr(int ierr) {
static constexpr PyObject *PyErr_SetFromWindowsErr(int ierr) {
PyErr_SetString(PyExc_OSError, "Call to EnumProcessModules failed");
return NULL;
return nullptr;
}
#endif

Expand Down
14 changes: 7 additions & 7 deletions src/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ class scalar
{
}

T &operator()(int i, int j = 0, int k = 0)
T &operator()([[maybe_unused]] int i, [[maybe_unused]] int j = 0, [[maybe_unused]] int k = 0)
{
return m_value;
}

const T &operator()(int i, int j = 0, int k = 0) const
const T &operator()([[maybe_unused]] int i, [[maybe_unused]] int j = 0, [[maybe_unused]] int k = 0) const
{
return m_value;
}

int shape(size_t i)
int shape([[maybe_unused]] size_t i)
{
return 1;
}
Expand All @@ -58,22 +58,22 @@ class empty

empty() = default;

T &operator()(int i, int j = 0, int k = 0)
T &operator()([[maybe_unused]] int i, [[maybe_unused]] int j = 0, [[maybe_unused]] int k = 0)
{
throw std::runtime_error("Accessed empty array");
}

const T &operator()(int i, int j = 0, int k = 0) const
const T &operator()([[maybe_unused]] int i, [[maybe_unused]] int j = 0, [[maybe_unused]] int k = 0) const
{
throw std::runtime_error("Accessed empty array");
}

sub_t operator[](int i) const
sub_t operator[]([[maybe_unused]] int i) const
{
return empty<T>();
}

int shape(size_t i) const
int shape([[maybe_unused]] size_t i) const
{
return 0;
}
Expand Down
26 changes: 20 additions & 6 deletions src/ft2font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
#include "mplutils.h"

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iterator>
#include <limits>
#include <map>
#include <set>
#include <stdexcept>
Expand All @@ -19,8 +21,18 @@
FT_Library _ft2Library;

FT2Image::FT2Image(unsigned long width, unsigned long height)
: m_buffer((unsigned char *)calloc(width * height, 1)), m_width(width), m_height(height)
: m_width(width), m_height(height)
{
size_t buffer_size = width * height;
if (buffer_size != 0 && buffer_size / width != height) {
const char* template_msg = "Cannot allocate a FT2Image "
"with the following arguments: width=%lu, height=%lu";
int sz = std::snprintf(nullptr, 0, template_msg, width, height);
std::vector<char> buf(sz + 1); // note +1 for null terminator
std::sprintf(buf.data(), template_msg, width, height); // certain to fit
throw std::overflow_error(buf.data());
}
m_buffer = static_cast<unsigned char *>(calloc(width * height, 1));
}

FT2Image::~FT2Image()
Expand Down Expand Up @@ -150,7 +162,10 @@ static FT_Outline_Funcs ft_outline_funcs = {
ft_outline_move_to,
ft_outline_line_to,
ft_outline_conic_to,
ft_outline_cubic_to};
ft_outline_cubic_to,
0,
0,
};

void
FT2Font::get_path(std::vector<double> &vertices, std::vector<unsigned char> &codes)
Expand All @@ -171,8 +186,7 @@ FT2Font::get_path(std::vector<double> &vertices, std::vector<unsigned char> &cod
codes.reserve(estimated_points);
if (FT_Error error = FT_Outline_Decompose(
&face->glyph->outline, &ft_outline_funcs, &decomposer)) {
throw std::runtime_error("FT_Outline_Decompose failed with error " +
std::to_string(error));
THROW_FT_ERROR("Decompose font outline", error);
}
if (vertices.empty()) { // Don't append CLOSEPOLY to null glyphs.
return;
Expand Down Expand Up @@ -476,12 +490,12 @@ void FT2Font::set_text(
FT_Error error;
error = FT_Load_Glyph(rglyph.ftface, rglyph.index, flags);
if (error) {
throw std::runtime_error("failed to load glyph");
THROW_FT_ERROR("Loading glyphs", error);
}
FT_Glyph thisGlyph;
error = FT_Get_Glyph(rglyph.ftface->glyph, &thisGlyph);
if (error) {
throw std::runtime_error("failed to get glyph");
THROW_FT_ERROR("Getting glyphs", error);
}

pen.x += rglyph.x_offset;
Expand Down
3 changes: 2 additions & 1 deletion src/ft2font.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
extern "C" {
#include <ft2build.h>
#include FT_BITMAP_H
#include FT_ERRORS_H
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
Expand All @@ -37,7 +38,7 @@ namespace py = pybind11;
#define FIXED_MINOR(val) (unsigned short)(val & 0xffff)

// Error handling (error codes are loaded as described in fterror.h).
inline char const* ft_error_string(FT_Error error) {
constexpr char const* ft_error_string(FT_Error error) {
#undef __FTERRORS_H__
#define FT_ERROR_START_LIST switch (error) {
#define FT_ERRORDEF( e, v, s ) case v: return s;
Expand Down
23 changes: 11 additions & 12 deletions src/ft2font_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <memory>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
Expand Down Expand Up @@ -322,7 +323,7 @@ PyGlyph_from_FT2Font(const FT2Font *font)
const FT_Face &face = font->get_face();
const FT_Glyph &glyph = font->get_last_glyph();

PyGlyph *self = new PyGlyph();
PyGlyph* self = new PyGlyph();

self->glyphInd = font->get_last_glyph_index();
FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_subpixels, &self->bbox);
Expand Down Expand Up @@ -370,11 +371,10 @@ class PyFT2Font final : public FT2Font

void ft_glyph_warn(FT_ULong charcode, std::set<FT_String*> family_names)
{
std::set<FT_String*>::iterator it = family_names.begin();
std::stringstream ss;
ss<< (*it ? *it : "unknown family name");
while(++it != family_names.end()){
ss<<", "<< (*it ? *it : "unknown family name");
std::ostringstream ss;
for (const auto& fname : family_names) {
ss << (fname != nullptr ? fname : "unknown family name");
if (fname != *family_names.rbegin()) ss << ", ";
}

auto text_helpers = py::module_::import("matplotlib._text_helpers");
Expand Down Expand Up @@ -438,16 +438,15 @@ read_from_file_callback(FT_Stream stream, unsigned long offset, unsigned char *b
static void
close_file_callback(FT_Stream stream)
{
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
PyObject* exc = PyErr_GetRaisedException();
PyFT2Font *self = (PyFT2Font *)stream->descriptor.pointer;
try {
self->py_file.attr("close")();
} catch (py::error_already_set &eas) {
eas.discard_as_unraisable(__func__);
}
self->py_file = py::object();
PyErr_Restore(type, value, traceback);
PyErr_SetRaisedException(exc);
}

const char *PyFT2Font_init__doc__ = R"""(
Expand All @@ -472,7 +471,7 @@ const char *PyFT2Font_init__doc__ = R"""(
This API is private: do not use it directly.
)""";

static PyFT2Font *
static std::unique_ptr<PyFT2Font>
PyFT2Font_init(py::object filename, std::optional<long> hinting_factor = std::nullopt,
FT_Long face_index = 0,
std::optional<std::vector<PyFT2Font *>> fallback_list = std::nullopt,
Expand Down Expand Up @@ -503,7 +502,7 @@ PyFT2Font_init(py::object filename, std::optional<long> hinting_factor = std::nu
std::back_inserter(fallback_fonts));
}

auto self = new PyFT2Font(fallback_fonts, warn_if_used);
auto self = std::make_unique<PyFT2Font>(fallback_fonts, warn_if_used);
self->set_kerning_factor(*kerning_factor);

if (fallback_list) {
Expand All @@ -517,7 +516,7 @@ PyFT2Font_init(py::object filename, std::optional<long> hinting_factor = std::nu
self->stream.base = nullptr;
self->stream.size = 0x7fffffff; // Unknown size.
self->stream.pos = 0;
self->stream.descriptor.pointer = self;
self->stream.descriptor.pointer = self.get();
self->stream.read = &read_from_file_callback;
FT_Open_Args open_args;
memset((void *)&open_args, 0, sizeof(FT_Open_Args));
Expand Down
8 changes: 4 additions & 4 deletions src/mplutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
#endif


inline int mpl_round_to_int(double v)
constexpr int mpl_round_to_int(double v)
{
return (int)(v + ((v >= 0.0) ? 0.5 : -0.5));
}

inline double mpl_round(double v)
constexpr double mpl_round(double v)
{
return (double)mpl_round_to_int(v);
}
Expand All @@ -60,7 +60,7 @@ namespace py = pybind11;
using namespace pybind11::literals;

template<typename T>
inline void check_trailing_shape(T array, char const* name, long d1)
constexpr void check_trailing_shape(T array, char const* name, long d1)
{
if (array.ndim() != 2) {
throw py::value_error(
Expand All @@ -79,7 +79,7 @@ inline void check_trailing_shape(T array, char const* name, long d1)
}

template<typename T>
inline void check_trailing_shape(T array, char const* name, long d1, long d2)
constexpr void check_trailing_shape(T array, char const* name, long d1, long d2)
{
if (array.ndim() != 3) {
throw py::value_error(
Expand Down
Loading
Loading