5
5
6
6
Python wrapper for TrueType conversion library in ../ttconv.
7
7
*/
8
- #define PY_SSIZE_T_CLEAN
9
8
#include " mplutils.h"
10
9
11
- #include < Python .h>
10
+ #include < pybind11/pybind11 .h>
12
11
#include " ttconv/pprdrv.h"
13
- #include " py_exceptions.h"
14
12
#include < vector>
15
- #include < cassert>
16
13
17
14
/* *
18
15
* An implementation of TTStreamWriter that writes to a Python
19
16
* file-like object.
20
17
*/
21
18
class PythonFileWriter : public TTStreamWriter
22
19
{
23
- PyObject * _write_method;
20
+ pybind11::function _write_method;
24
21
25
22
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" )) {}
42
25
43
26
virtual void write (const char *a)
44
27
{
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 ();
58
31
}
32
+ _write_method (pybind11::handle (decoded));
33
+ Py_DECREF (decoded);
59
34
}
60
35
};
61
36
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
- }
F438
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)
37
+ static void convert_ttf_to_ps (
38
+ const char *filename,
39
+ pybind11::object &output,
40
+ int fonttype,
41
+ pybind11::iterable glyph_ids)
79
42
{
80
- std::vector<int > *result = (std::vector<int > *)address;
43
+ PythonFileWriter output_ (output);
44
+ std::vector<int > glyph_ids_;
81
45
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)
103
- {
104
- const char *filename;
105
- PythonFileWriter output;
106
- int fonttype;
107
- std::vector<int > glyph_ids;
108
-
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 >());
121
48
}
122
49
123
50
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)" );
128
53
}
129
54
130
55
try
131
56
{
132
- insert_ttfont (filename, output, ( font_type_enum) fonttype, glyph_ids );
57
+ insert_ttfont (filename, output_, static_cast < font_type_enum>( fonttype), glyph_ids_ );
133
58
}
134
59
catch (TTException &e)
135
60
{
136
- PyErr_SetString (PyExc_RuntimeError, e.getMessage ());
137
- return NULL ;
138
- }
139
- catch (const py::exception &)
140
- {
141
- return NULL ;
61
+ throw std::runtime_error (e.getMessage ());
142
62
}
143
63
catch (...)
144
64
{
145
- PyErr_SetString (PyExc_RuntimeError, " Unknown C++ exception" );
146
- return NULL ;
65
+ throw std::runtime_error (" Unknown C++ exception" );
147
66
}
148
-
149
- Py_INCREF (Py_None);
150
- return Py_None;
151
67
}
152
68
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 "
69
+ PYBIND11_MODULE (_ttconv, m) {
70
+ m.doc () = " Module to handle converting and subsetting TrueType "
71
+ " fonts to Postscript Type 3, Postscript Type 42 and "
72
+ " Pdf Type 3 fonts." ;
73
+ m.def (" convert_ttf_to_ps" , &convert_ttf_to_ps,
74
+ pybind11::arg (" filename" ),
75
+ pybind11::arg (" output" ),
76
+ pybind11::arg (" fonttype" ),
77
+ pybind11::arg (" glyph_ids" ),
159
78
" Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
160
79
" optionally subsetting the font to only the desired set of characters.\n "
161
80
" \n "
@@ -169,29 +88,5 @@ static PyMethodDef ttconv_methods[] =
169
88
" subsetting to a Type 3 font. If glyph_ids is not provided or is None, "
170
89
" then all glyphs will be included. If any of the glyphs specified are "
171
90
" 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);
91
+ );
195
92
}
196
-
197
- #pragma GCC visibility pop
0 commit comments