Blender V4.3
blf_py_api.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11/* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
12#define PY_SSIZE_T_CLEAN
13
14#include "blf_py_api.hh"
15
17
18#include <Python.h>
19
21
22#include "BLI_utildefines.h"
23
24#include "python_utildefines.hh"
25
27 /* Wrap. */
28 py_blf_position_doc,
29 ".. function:: position(fontid, x, y, z)\n"
30 "\n"
31 " Set the position for drawing text.\n"
32 "\n"
33 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
34 "font use 0.\n"
35 " :type fontid: int\n"
36 " :arg x: X axis position to draw the text.\n"
37 " :type x: float\n"
38 " :arg y: Y axis position to draw the text.\n"
39 " :type y: float\n"
40 " :arg z: Z axis position to draw the text.\n"
41 " :type z: float\n");
42
43static PyObject *py_blf_position(PyObject * /*self*/, PyObject *args)
44{
45 int fontid;
46 float x, y, z;
47
48 if (!PyArg_ParseTuple(args, "ifff:blf.position", &fontid, &x, &y, &z)) {
49 return nullptr;
50 }
51
52 BLF_position(fontid, x, y, z);
53
54 Py_RETURN_NONE;
55}
56
58 /* Wrap. */
59 py_blf_size_doc,
60 ".. function:: size(fontid, size)\n"
61 "\n"
62 " Set the size for drawing text.\n"
63 "\n"
64 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
65 "font use 0.\n"
66 " :type fontid: int\n"
67 " :arg size: Point size of the font.\n"
68 " :type size: float\n");
69static PyObject *py_blf_size(PyObject * /*self*/, PyObject *args)
70{
71 int fontid;
72 float size;
73
74 if (!PyArg_ParseTuple(args, "if:blf.size", &fontid, &size)) {
75 return nullptr;
76 }
77
78 BLF_size(fontid, size);
79
80 Py_RETURN_NONE;
81}
82
84 /* Wrap. */
85 py_blf_aspect_doc,
86 ".. function:: aspect(fontid, aspect)\n"
87 "\n"
88 " Set the aspect for drawing text.\n"
89 "\n"
90 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
91 "font use 0.\n"
92 " :type fontid: int\n"
93 " :arg aspect: The aspect ratio for text drawing to use.\n"
94 " :type aspect: float\n");
95static PyObject *py_blf_aspect(PyObject * /*self*/, PyObject *args)
96{
97 float aspect;
98 int fontid;
99
100 if (!PyArg_ParseTuple(args, "if:blf.aspect", &fontid, &aspect)) {
101 return nullptr;
102 }
103
104 BLF_aspect(fontid, aspect, aspect, 1.0);
105
106 Py_RETURN_NONE;
107}
108
110 /* Wrap. */
111 py_blf_color_doc,
112 ".. function:: color(fontid, r, g, b, a)\n"
113 "\n"
114 " Set the color for drawing text.\n"
115 "\n"
116 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
117 "font use 0.\n"
118 " :type fontid: int\n"
119 " :arg r: red channel 0.0 - 1.0.\n"
120 " :type r: float\n"
121 " :arg g: green channel 0.0 - 1.0.\n"
122 " :type g: float\n"
123 " :arg b: blue channel 0.0 - 1.0.\n"
124 " :type b: float\n"
125 " :arg a: alpha channel 0.0 - 1.0.\n"
126 " :type a: float\n");
127static PyObject *py_blf_color(PyObject * /*self*/, PyObject *args)
128{
129 int fontid;
130 float rgba[4];
131
132 if (!PyArg_ParseTuple(args, "iffff:blf.color", &fontid, &rgba[0], &rgba[1], &rgba[2], &rgba[3]))
133 {
134 return nullptr;
135 }
136
137 BLF_color4fv(fontid, rgba);
138
139 Py_RETURN_NONE;
140}
141
143 /* Wrap. */
144 py_blf_draw_doc,
145 ".. function:: draw(fontid, text)\n"
146 "\n"
147 " Draw text in the current context.\n"
148 "\n"
149 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
150 "font use 0.\n"
151 " :type fontid: int\n"
152 " :arg text: the text to draw.\n"
153 " :type text: str\n");
154static PyObject *py_blf_draw(PyObject * /*self*/, PyObject *args)
155{
156 const char *text;
157 Py_ssize_t text_length;
158 int fontid;
159
160 if (!PyArg_ParseTuple(args, "is#:blf.draw", &fontid, &text, &text_length)) {
161 return nullptr;
162 }
163
164 BLF_draw(fontid, text, uint(text_length));
165
166 Py_RETURN_NONE;
167}
168
170 /* Wrap. */
171 py_blf_dimensions_doc,
172 ".. function:: dimensions(fontid, text)\n"
173 "\n"
174 " Return the width and height of the text.\n"
175 "\n"
176 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
177 "font use 0.\n"
178 " :type fontid: int\n"
179 " :arg text: the text to draw.\n"
180 " :type text: str\n"
181 " :return: the width and height of the text.\n"
182 " :rtype: tuple[float, float]\n");
183static PyObject *py_blf_dimensions(PyObject * /*self*/, PyObject *args)
184{
185 const char *text;
186 float r_width, r_height;
187 PyObject *ret;
188 int fontid;
189
190 if (!PyArg_ParseTuple(args, "is:blf.dimensions", &fontid, &text)) {
191 return nullptr;
192 }
193
194 BLF_width_and_height(fontid, text, INT_MAX, &r_width, &r_height);
195
196 ret = PyTuple_New(2);
197 PyTuple_SET_ITEMS(ret, PyFloat_FromDouble(r_width), PyFloat_FromDouble(r_height));
198 return ret;
199}
200
202 /* Wrap. */
203 py_blf_clipping_doc,
204 ".. function:: clipping(fontid, xmin, ymin, xmax, ymax)\n"
205 "\n"
206 " Set the clipping, enable/disable using CLIPPING.\n"
207 "\n"
208 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
209 "font use 0.\n"
210 " :type fontid: int\n"
211 " :arg xmin: Clip the drawing area by these bounds.\n"
212 " :type xmin: float\n"
213 " :arg ymin: Clip the drawing area by these bounds.\n"
214 " :type ymin: float\n"
215 " :arg xmax: Clip the drawing area by these bounds.\n"
216 " :type xmax: float\n"
217 " :arg ymax: Clip the drawing area by these bounds.\n"
218 " :type ymax: float\n");
219static PyObject *py_blf_clipping(PyObject * /*self*/, PyObject *args)
220{
221 float xmin, ymin, xmax, ymax;
222 int fontid;
223
224 if (!PyArg_ParseTuple(args, "iffff:blf.clipping", &fontid, &xmin, &ymin, &xmax, &ymax)) {
225 return nullptr;
226 }
227
228 BLF_clipping(fontid, xmin, ymin, xmax, ymax);
229
230 Py_RETURN_NONE;
231}
232
234 /* Wrap. */
235 py_blf_word_wrap_doc,
236 ".. function:: word_wrap(fontid, wrap_width)\n"
237 "\n"
238 " Set the wrap width, enable/disable using WORD_WRAP.\n"
239 "\n"
240 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
241 "font use 0.\n"
242 " :type fontid: int\n"
243 " :arg wrap_width: The width (in pixels) to wrap words at.\n"
244 " :type wrap_width: int\n");
245static PyObject *py_blf_word_wrap(PyObject * /*self*/, PyObject *args)
246{
247 int wrap_width;
248 int fontid;
249
250 if (!PyArg_ParseTuple(args, "ii:blf.word_wrap", &fontid, &wrap_width)) {
251 return nullptr;
252 }
253
254 BLF_wordwrap(fontid, wrap_width);
255
256 Py_RETURN_NONE;
257}
258
260 /* Wrap. */
261 py_blf_disable_doc,
262 ".. function:: disable(fontid, option)\n"
263 "\n"
264 " Disable option.\n"
265 "\n"
266 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
267 "font use 0.\n"
268 " :type fontid: int\n"
269 " :arg option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
270 " :type option: int\n");
271static PyObject *py_blf_disable(PyObject * /*self*/, PyObject *args)
272{
273 int option, fontid;
274
275 if (!PyArg_ParseTuple(args, "ii:blf.disable", &fontid, &option)) {
276 return nullptr;
277 }
278
279 BLF_disable(fontid, option);
280
281 Py_RETURN_NONE;
282}
283
285 /* Wrap. */
286 py_blf_enable_doc,
287 ".. function:: enable(fontid, option)\n"
288 "\n"
289 " Enable option.\n"
290 "\n"
291 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
292 "font use 0.\n"
293 " :type fontid: int\n"
294 " :arg option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
295 " :type option: int\n");
296static PyObject *py_blf_enable(PyObject * /*self*/, PyObject *args)
297{
298 int option, fontid;
299
300 if (!PyArg_ParseTuple(args, "ii:blf.enable", &fontid, &option)) {
301 return nullptr;
302 }
303
304 BLF_enable(fontid, option);
305
306 Py_RETURN_NONE;
307}
308
310 /* Wrap. */
311 py_blf_rotation_doc,
312 ".. function:: rotation(fontid, angle)\n"
313 "\n"
314 " Set the text rotation angle, enable/disable using ROTATION.\n"
315 "\n"
316 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
317 "font use 0.\n"
318 " :type fontid: int\n"
319 " :arg angle: The angle for text drawing to use.\n"
320 " :type angle: float\n");
321static PyObject *py_blf_rotation(PyObject * /*self*/, PyObject *args)
322{
323 float angle;
324 int fontid;
325
326 if (!PyArg_ParseTuple(args, "if:blf.rotation", &fontid, &angle)) {
327 return nullptr;
328 }
329
330 BLF_rotation(fontid, angle);
331
332 Py_RETURN_NONE;
333}
334
336 /* Wrap. */
337 py_blf_shadow_doc,
338 ".. function:: shadow(fontid, level, r, g, b, a)\n"
339 "\n"
340 " Shadow options, enable/disable using SHADOW .\n"
341 "\n"
342 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
343 "font use 0.\n"
344 " :type fontid: int\n"
345 " :arg level: The blur level (0, 3, 5) or outline (6).\n"
346 " :type level: int\n"
347 " :arg r: Shadow color (red channel 0.0 - 1.0).\n"
348 " :type r: float\n"
349 " :arg g: Shadow color (green channel 0.0 - 1.0).\n"
350 " :type g: float\n"
351 " :arg b: Shadow color (blue channel 0.0 - 1.0).\n"
352 " :type b: float\n"
353 " :arg a: Shadow color (alpha channel 0.0 - 1.0).\n"
354 " :type a: float\n");
355static PyObject *py_blf_shadow(PyObject * /*self*/, PyObject *args)
356{
357 int level, fontid;
358 float rgba[4];
359
360 if (!PyArg_ParseTuple(
361 args, "iiffff:blf.shadow", &fontid, &level, &rgba[0], &rgba[1], &rgba[2], &rgba[3]))
362 {
363 return nullptr;
364 }
365
366 if (!ELEM(level, 0, 3, 5, 6)) {
367 PyErr_SetString(PyExc_TypeError, "blf.shadow expected arg to be in (0, 3, 5, 6)");
368 return nullptr;
369 }
370
371 BLF_shadow(fontid, FontShadowType(level), rgba);
372
373 Py_RETURN_NONE;
374}
375
377 /* Wrap. */
378 py_blf_shadow_offset_doc,
379 ".. function:: shadow_offset(fontid, x, y)\n"
380 "\n"
381 " Set the offset for shadow text.\n"
382 "\n"
383 " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default "
384 "font use 0.\n"
385 " :type fontid: int\n"
386 " :arg x: Vertical shadow offset value in pixels.\n"
387 " :type x: float\n"
388 " :arg y: Horizontal shadow offset value in pixels.\n"
389 " :type y: float\n");
390static PyObject *py_blf_shadow_offset(PyObject * /*self*/, PyObject *args)
391{
392 int x, y, fontid;
393
394 if (!PyArg_ParseTuple(args, "iii:blf.shadow_offset", &fontid, &x, &y)) {
395 return nullptr;
396 }
397
398 BLF_shadow_offset(fontid, x, y);
399
400 Py_RETURN_NONE;
401}
402
404 /* Wrap. */
405 py_blf_load_doc,
406 ".. function:: load(filepath)\n"
407 "\n"
408 " Load a new font.\n"
409 "\n"
410 " :arg filepath: the filepath of the font.\n"
411 " :type filepath: str | bytes\n"
412 " :return: the new font's fontid or -1 if there was an error.\n"
413 " :rtype: int\n");
414static PyObject *py_blf_load(PyObject * /*self*/, PyObject *args)
415{
416 PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
417 if (!PyArg_ParseTuple(args,
418 "O&" /* `filepath` */
419 ":blf.load",
421 &filepath_data))
422 {
423 return nullptr;
424 }
425 const int font_id = BLF_load(filepath_data.value);
426 Py_XDECREF(filepath_data.value_coerce);
427
428 return PyLong_FromLong(font_id);
429}
430
432 /* Wrap. */
433 py_blf_unload_doc,
434 ".. function:: unload(filepath)\n"
435 "\n"
436 " Unload an existing font.\n"
437 "\n"
438 " :arg filepath: the filepath of the font.\n"
439 " :type filepath: str | bytes\n");
440static PyObject *py_blf_unload(PyObject * /*self*/, PyObject *args)
441{
442 PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
443 if (!PyArg_ParseTuple(args,
444 "O&" /* `filepath` */
445 ":blf.unload",
447 &filepath_data))
448 {
449 return nullptr;
450 }
451
452 BLF_unload(filepath_data.value);
453 Py_XDECREF(filepath_data.value_coerce);
454
455 Py_RETURN_NONE;
456}
457
458/*----------------------------MODULE INIT-------------------------*/
459static PyMethodDef BLF_methods[] = {
460 {"aspect", (PyCFunction)py_blf_aspect, METH_VARARGS, py_blf_aspect_doc},
461 {"clipping", (PyCFunction)py_blf_clipping, METH_VARARGS, py_blf_clipping_doc},
462 {"word_wrap", (PyCFunction)py_blf_word_wrap, METH_VARARGS, py_blf_word_wrap_doc},
463 {"disable", (PyCFunction)py_blf_disable, METH_VARARGS, py_blf_disable_doc},
464 {"dimensions", (PyCFunction)py_blf_dimensions, METH_VARARGS, py_blf_dimensions_doc},
465 {"draw", (PyCFunction)py_blf_draw, METH_VARARGS, py_blf_draw_doc},
466 {"enable", (PyCFunction)py_blf_enable, METH_VARARGS, py_blf_enable_doc},
467 {"position", (PyCFunction)py_blf_position, METH_VARARGS, py_blf_position_doc},
468 {"rotation", (PyCFunction)py_blf_rotation, METH_VARARGS, py_blf_rotation_doc},
469 {"shadow", (PyCFunction)py_blf_shadow, METH_VARARGS, py_blf_shadow_doc},
470 {"shadow_offset", (PyCFunction)py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc},
471 {"size", (PyCFunction)py_blf_size, METH_VARARGS, py_blf_size_doc},
472 {"color", (PyCFunction)py_blf_color, METH_VARARGS, py_blf_color_doc},
473 {"load", (PyCFunction)py_blf_load, METH_VARARGS, py_blf_load_doc},
474 {"unload", (PyCFunction)py_blf_unload, METH_VARARGS, py_blf_unload_doc},
475 {nullptr, nullptr, 0, nullptr},
476};
477
479 /* Wrap. */
480 BLF_doc,
481 "This module provides access to Blender's text drawing functions.");
482static PyModuleDef BLF_module_def = {
483 /*m_base*/ PyModuleDef_HEAD_INIT,
484 /*m_name*/ "blf",
485 /*m_doc*/ BLF_doc,
486 /*m_size*/ 0,
487 /*m_methods*/ BLF_methods,
488 /*m_slots*/ nullptr,
489 /*m_traverse*/ nullptr,
490 /*m_clear*/ nullptr,
491 /*m_free*/ nullptr,
492};
493
494PyObject *BPyInit_blf()
495{
496 PyObject *submodule;
497
498 submodule = PyModule_Create(&BLF_module_def);
499
500 PyModule_AddIntConstant(submodule, "ROTATION", BLF_ROTATION);
501 PyModule_AddIntConstant(submodule, "CLIPPING", BLF_CLIPPING);
502 PyModule_AddIntConstant(submodule, "SHADOW", BLF_SHADOW);
503 PyModule_AddIntConstant(submodule, "WORD_WRAP", BLF_WORD_WRAP);
504 PyModule_AddIntConstant(submodule, "MONOCHROME", BLF_MONOCHROME);
505
506 return submodule;
507}
void BLF_size(int fontid, float size)
Definition blf.cc:426
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4]=nullptr)
Definition blf.cc:902
void BLF_aspect(int fontid, float x, float y, float z)
Definition blf.cc:360
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
Definition blf.cc:881
void BLF_width_and_height(int fontid, const char *str, size_t str_len, float *r_width, float *r_height) ATTR_NONNULL()
Definition blf.cc:778
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:488
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:914
void BLF_disable(int fontid, int option)
Definition blf.cc:321
void BLF_rotation(int fontid, float angle)
Definition blf.cc:872
void BLF_draw(int fontid, const char *str, size_t str_len, ResultBLF *r_info=nullptr) ATTR_NONNULL(2)
Definition blf.cc:568
int BLF_load(const char *filepath) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition blf.cc:174
void BLF_enable(int fontid, int option)
Definition blf.cc:312
FontShadowType
Definition BLF_api.hh:33
@ BLF_ROTATION
Definition BLF_api.hh:361
@ BLF_WORD_WRAP
Definition BLF_api.hh:367
@ BLF_MONOCHROME
Definition BLF_api.hh:369
@ BLF_SHADOW
Definition BLF_api.hh:363
@ BLF_CLIPPING
Definition BLF_api.hh:362
int void BLF_unload(const char *filepath) ATTR_NONNULL(1)
Definition blf.cc:264
void BLF_wordwrap(int fontid, int wrap_width)
Definition blf.cc:893
void BLF_position(int fontid, float x, float y, float z)
Definition blf.cc:371
unsigned int uint
#define ELEM(...)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
static PyObject * py_blf_word_wrap(PyObject *, PyObject *args)
PyObject * BPyInit_blf()
static PyObject * py_blf_enable(PyObject *, PyObject *args)
static PyObject * py_blf_aspect(PyObject *, PyObject *args)
Definition blf_py_api.cc:95
static PyModuleDef BLF_module_def
static PyObject * py_blf_color(PyObject *, PyObject *args)
static PyObject * py_blf_shadow_offset(PyObject *, PyObject *args)
static PyMethodDef BLF_methods[]
static PyObject * py_blf_unload(PyObject *, PyObject *args)
static PyObject * py_blf_load(PyObject *, PyObject *args)
static PyObject * py_blf_shadow(PyObject *, PyObject *args)
static PyObject * py_blf_dimensions(PyObject *, PyObject *args)
static PyObject * py_blf_clipping(PyObject *, PyObject *args)
static PyObject * py_blf_rotation(PyObject *, PyObject *args)
static PyObject * py_blf_disable(PyObject *, PyObject *args)
static PyObject * py_blf_draw(PyObject *, PyObject *args)
static PyObject * py_blf_size(PyObject *, PyObject *args)
Definition blf_py_api.cc:69
PyDoc_STRVAR(py_blf_position_doc, ".. function:: position(fontid, x, y, z)\n" "\n" " Set the position for drawing text.\n" "\n" " :arg fontid: The id of the typeface as returned by :func:`blf.load`, for default " "font use 0.\n" " :type fontid: int\n" " :arg x: X axis position to draw the text.\n" " :type x: float\n" " :arg y: Y axis position to draw the text.\n" " :type y: float\n" " :arg z: Z axis position to draw the text.\n" " :type z: float\n")
static PyObject * py_blf_position(PyObject *, PyObject *args)
Definition blf_py_api.cc:43
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
int PyC_ParseUnicodeAsBytesAndSize(PyObject *o, void *p)
header-only utilities
#define PyTuple_SET_ITEMS(op_arg,...)
return ret