Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a53da51

Browse filesBrowse files
committed
Use pybind11 in ttconv module
1 parent 238e275 commit a53da51
Copy full SHA for a53da51

File tree

2 files changed

+39
-137
lines changed
Filter options

2 files changed

+39
-137
lines changed

‎setupext.py

Copy file name to clipboardExpand all lines: setupext.py
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,14 +468,15 @@ def get_extensions(self):
468468
cxx_std=11)
469469
yield ext
470470
# ttconv
471-
ext = Extension(
471+
ext = Pybind11Extension(
472472
"matplotlib._ttconv", [
473473
"src/_ttconv.cpp",
474474
"extern/ttconv/pprdrv_tt.cpp",
475475
"extern/ttconv/pprdrv_tt2.cpp",
476476
"extern/ttconv/ttutil.cpp",
477477
],
478-
include_dirs=["extern"])
478+
include_dirs=["extern"],
479+
cxx_std=11)
479480
add_numpy_flags(ext)
480481
yield ext
481482

‎src/_ttconv.cpp

Copy file name to clipboardExpand all lines: src/_ttconv.cpp
+36-135Lines changed: 36 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -5,157 +5,82 @@
55
66
Python wrapper for TrueType conversion library in ../ttconv.
77
*/
8-
#define PY_SSIZE_T_CLEAN
98
#include "mplutils.h"
109

11-
#include <Python.h>
10+
#include <pybind11/pybind11.h>
1211
#include "ttconv/pprdrv.h"
13-
#include "py_exceptions.h"
1412
#include <vector>
15-
#include <cassert>
1613

1714
/**
1815
* An implementation of TTStreamWriter that writes to a Python
1916
* file-like object.
2017
*/
2118
class PythonFileWriter : public TTStreamWriter
2219
{
23-
PyObject *_write_method;
20+
pybind11::function _write_method;
2421

2522
public:
26-
PythonFileWriter()
27-
{
28-
_write_method = NULL;
29-
}
30-
31-
~PythonFileWriter()
32-
{
33-
Py_XDECREF(_write_method);
34-
}
35-
36-
void set(PyObject *write_method)
37-
{
38-
Py_XDECREF(_write_method);
39-
_write_method = write_method;
40-
Py_XINCREF(_write_method);
41-
}
23+
PythonFileWriter(pybind11::object& file_object)
24+
: _write_method(file_object.attr("write")) {}
4225

4326
virtual void write(const char *a)
4427
{
45-
PyObject *result = NULL;
46-
if (_write_method) {
47-
PyObject *decoded = NULL;
48-
decoded = PyUnicode_DecodeLatin1(a, strlen(a), "");
49-
if (decoded == NULL) {
50-
throw py::exception();
51-
}
52-
result = PyObject_CallFunctionObjArgs(_write_method, decoded, NULL);
53-
Py_DECREF(decoded);
54-
if (!result) {
55-
throw py::exception();
56-
}
57-
Py_DECREF(result);
28+
PyObject* decoded = PyUnicode_DecodeLatin1(a, strlen(a), "");
29+
if (decoded == NULL) {
30+
throw pybind11::error_already_set();
5831
}
32+
_write_method(pybind11::handle(decoded));
33+
Py_DECREF(decoded);
5934
}
6035
};
6136

62-
int fileobject_to_PythonFileWriter(PyObject *object, void *address)
63-
{
64-
PythonFileWriter *file_writer = (PythonFileWriter *)address;
65-
66-
PyObject *write_method = PyObject_GetAttrString(object, "write");
67-
if (write_method == NULL || !PyCallable_Check(write_method)) {
68-
PyErr_SetString(PyExc_TypeError, "Expected a file-like object with a write method.");
69-
return 0;
70-
}
71-
72-
file_writer->set(write_method);
73-
Py_DECREF(write_method);
74-
75-
return 1;
76-
}
77-
78-
int pyiterable_to_vector_int(PyObject *object, void *address)
79-
{
80-
std::vector<int> *result = (std::vector<int> *)address;
81-
82-
PyObject *iterator = PyObject_GetIter(object);
83-
if (!iterator) {
84-
return 0;
85-
}
86-
87-
PyObject *item;
88-
while ((item = PyIter_Next(iterator))) {
89-
long value = PyLong_AsLong(item);
90-
Py_DECREF(item);
91-
if (value == -1 && PyErr_Occurred()) {
92-
return 0;
93-
}
94-
result->push_back((int)value);
95-
}
96-
97-
Py_DECREF(iterator);
98-
99-
return 1;
100-
}
101-
102-
static PyObject *convert_ttf_to_ps(PyObject *self, PyObject *args, PyObject *kwds)
37+
static void convert_ttf_to_ps(
38+
const char *filename,
39+
pybind11::object &output,
40+
int fonttype,
41+
pybind11::iterable glyph_ids)
10342
{
104-
const char *filename;
105-
PythonFileWriter output;
106-
int fonttype;
107-
std::vector<int> glyph_ids;
43+
PythonFileWriter output_(output);
44+
std::vector<int> glyph_ids_;
10845

109-
static const char *kwlist[] = { "filename", "output", "fonttype", "glyph_ids", NULL };
110-
if (!PyArg_ParseTupleAndKeywords(args,
111-
kwds,
112-
"yO&i|O&:convert_ttf_to_ps",
113-
(char **)kwlist,
114-
&filename,
115-
fileobject_to_PythonFileWriter,
116-
&output,
117-
&fonttype,
118-
pyiterable_to_vector_int,
119-
&glyph_ids)) {
120-
return NULL;
46+
for (pybind11::handle glyph_id: glyph_ids) {
47+
glyph_ids_.push_back(glyph_id.cast<int>());
12148
}
12249

12350
if (fonttype != 3 && fonttype != 42) {
124-
PyErr_SetString(PyExc_ValueError,
125-
"fonttype must be either 3 (raw Postscript) or 42 "
126-
"(embedded Truetype)");
127-
return NULL;
51+
throw pybind11::value_error(
52+
"fonttype must be either 3 (raw Postscript) or 42 (embedded Truetype)");
12853
}
12954

13055
try
13156
{
132-
insert_ttfont(filename, output, (font_type_enum)fonttype, glyph_ids);
57+
insert_ttfont(filename, output_, static_cast<font_type_enum>(fonttype), glyph_ids_);
13358
}
13459
catch (TTException &e)
13560
{
136-
PyErr_SetString(PyExc_RuntimeError, e.getMessage());
137-
return NULL;
61+
throw std::runtime_error(e.getMessage());
13862
}
139-
catch (const py::exception &)
63+
catch (pybind11::error_already_set &)
14064
{
141-
return NULL;
65+
return;
14266
}
14367
catch (...)
14468
{
145-
PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
146-
return NULL;
69+
throw std::runtime_error("Unknown C++ exception");
14770
}
14871

149-
Py_INCREF(Py_None);
150-
return Py_None;
72+
return;
15173
}
15274

153-
static PyMethodDef ttconv_methods[] =
154-
{
155-
{
156-
"convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, METH_VARARGS | METH_KEYWORDS,
157-
"convert_ttf_to_ps(filename, output, fonttype, glyph_ids)\n"
158-
"\n"
75+
PYBIND11_MODULE(_ttconv, m) {
76+
m.doc() = "Module to handle converting and subsetting TrueType "
77+
"fonts to Postscript Type 3, Postscript Type 42 and "
78+
"Pdf Type 3 fonts.";
79+
m.def("convert_ttf_to_ps", &convert_ttf_to_ps,
80+
pybind11::arg("filename"),
81+
pybind11::arg("output"),
82+
pybind11::arg("fonttype"),
83+
pybind11::arg("glyph_ids"),
15984
"Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
16085
"optionally subsetting the font to only the desired set of characters.\n"
16186
"\n"
@@ -169,29 +94,5 @@ static PyMethodDef ttconv_methods[] =
16994
"subsetting to a Type 3 font. If glyph_ids is not provided or is None, "
17095
"then all glyphs will be included. If any of the glyphs specified are "
17196
"composite glyphs, then the component glyphs will also be included."
172-
},
173-
{0, 0, 0, 0} /* Sentinel */
174-
};
175-
176-
static const char *module_docstring =
177-
"Module to handle converting and subsetting TrueType "
178-
"fonts to Postscript Type 3, Postscript Type 42 and "
179-
"Pdf Type 3 fonts.";
180-
181-
static PyModuleDef ttconv_module = {
182-
PyModuleDef_HEAD_INIT,
183-
"ttconv",
184-
module_docstring,
185-
-1,
186-
ttconv_methods,
187-
};
188-
189-
#pragma GCC visibility push(default)
190-
191-
PyMODINIT_FUNC
192-
PyInit__ttconv(void)
193-
{
194-
return PyModule_Create(&ttconv_module);
97+
);
19598
}
196-
197-
#pragma GCC visibility pop

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.