2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup pygen
|
2011-11-05 08:40:07 +00:00
|
|
|
*
|
2025-03-13 13:41:17 +11:00
|
|
|
* This file defines the `bgl` module, used for drawing text in OpenGL.
|
2011-02-27 20:10:08 +00:00
|
|
|
*/
|
|
|
|
|
|
2019-10-16 15:55:47 +11:00
|
|
|
/* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
|
|
|
|
|
#define PY_SSIZE_T_CLEAN
|
|
|
|
|
|
2024-09-24 15:25:36 +02:00
|
|
|
#include "blf_py_api.hh"
|
2023-08-11 14:59:55 +10:00
|
|
|
|
2024-09-24 15:25:36 +02:00
|
|
|
#include "../generic/py_capi_utils.hh"
|
2023-08-11 14:59:55 +10:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <Python.h>
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2024-01-31 14:04:56 -05:00
|
|
|
#include "../../blenfont/BLF_api.hh"
|
2011-01-07 18:36:47 +00:00
|
|
|
|
|
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
2025-03-15 08:58:50 +11:00
|
|
|
#include "../../imbuf/IMB_colormanagement.hh"
|
|
|
|
|
#include "../../imbuf/IMB_imbuf.hh"
|
|
|
|
|
#include "../../imbuf/IMB_imbuf_types.hh"
|
|
|
|
|
|
|
|
|
|
#include "python_compat.hh"
|
2024-09-24 15:25:36 +02:00
|
|
|
#include "python_utildefines.hh"
|
2015-01-06 16:42:22 +11:00
|
|
|
|
2025-03-15 08:58:50 +11:00
|
|
|
#include "imbuf_py_api.hh"
|
|
|
|
|
|
|
|
|
|
struct BPyBLFImBufContext {
|
|
|
|
|
PyObject_HEAD /* Required Python macro. */
|
|
|
|
|
PyObject *py_imbuf;
|
Refactor: OpenColorIO integration
Briefly about this change:
- OpenColorIO C-API is removed.
- The information about color spaces in ImBuf module is removed.
It was stored in global ListBase in colormanagement.cc.
- Both OpenColorIO and fallback implementation supports GPU drawing.
- Fallback implementation supports white point, RGB curves, etc.
- Removed check for support of GPU drawing in IMB.
Historically it was implemented in a separate library with C-API, this
is because way back C++ code needed to stay in intern. This causes all
sort of overheads, and even calls that are strictly considered bad
level.
This change moves OpenColorIO integration into a module within imbuf,
next to movie, and next to IMB_colormanagement which is the main user
of it. This allows to avoid copy of color spaces, displays, views etc
in the ImBuf: they were used to help quickly querying information to
be shown on the interface. With this change it can be stored in the
same data structures as what is used by the OpenColorIO integration.
While it might not be fully avoiding duplication it is now less, and
there is no need in the user code to maintain the copies.
In a lot of cases this change also avoids allocations done per access
to the OpenColorIO. For example, it is not needed anymore to allocate
image descriptor in a heap.
The bigger user-visible change is that the fallback implementation now
supports GLSL drawing, with the whole list of supported features, such
as curve mapping and white point. This should help simplifying code
which relies on color space conversion on GPU: there is no need to
figure out fallback solution in such cases. The only case when drawing
will not work is when there is some actual bug, or driver issue, and
shader has failed to compile.
The change avoids having an opaque type for color space, and instead
uses forward declaration. It is a bit verbose on declaration, but helps
avoiding unsafe type-casts. There are ways to solve this in the future,
like having a header for forward declaration, or to flatten the name
space a bit.
There should be no user-level changes under normal operation.
When building without OpenColorIO or the configuration has a typo or
is missing a fuller set of color management tools is applies (such as the
white point correction).
Pull Request: https://projects.blender.org/blender/blender/pulls/138433
2025-05-09 14:01:43 +02:00
|
|
|
const ColorManagedDisplay *display;
|
2025-03-15 08:58:50 +11:00
|
|
|
|
|
|
|
|
int fontid;
|
|
|
|
|
BLFBufferState *buffer_state;
|
|
|
|
|
};
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
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");
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_position(PyObject * /*self*/, PyObject *args)
|
2010-02-28 11:18:54 +00:00
|
|
|
{
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int fontid;
|
2010-02-28 11:18:54 +00:00
|
|
|
float x, y, z;
|
|
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "ifff:blf.position", &fontid, &x, &y, &z)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-02-28 11:18:54 +00:00
|
|
|
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
BLF_position(fontid, x, y, z);
|
2010-02-28 11:18:54 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_size_doc,
|
|
|
|
|
".. function:: size(fontid, size)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the size 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 size: Point size of the font.\n"
|
|
|
|
|
" :type size: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_size(PyObject * /*self*/, PyObject *args)
|
2010-02-28 11:18:54 +00:00
|
|
|
{
|
2023-05-23 12:02:10 +10:00
|
|
|
int fontid;
|
2021-11-13 09:39:18 -08:00
|
|
|
float size;
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2023-05-23 12:02:10 +10:00
|
|
|
if (!PyArg_ParseTuple(args, "if:blf.size", &fontid, &size)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2022-09-23 17:36:49 -07:00
|
|
|
BLF_size(fontid, size);
|
2010-02-28 11:18:54 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_aspect_doc,
|
|
|
|
|
".. function:: aspect(fontid, aspect)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the aspect 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 aspect: The aspect ratio for text drawing to use.\n"
|
|
|
|
|
" :type aspect: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_aspect(PyObject * /*self*/, PyObject *args)
|
2010-02-28 11:18:54 +00:00
|
|
|
{
|
|
|
|
|
float aspect;
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int fontid;
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "if:blf.aspect", &fontid, &aspect)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-02-28 11:18:54 +00:00
|
|
|
|
Change the BLF_aspect function to handle 3d text.
This is need to properly handle 3d text (dalai work on GE), before
the BLF_aspect only take one argument, and the result was a call to:
glScalef(aspect, aspect, 1.0)
Now the three value are store in the font (x, y and z) and also
need to be enable using BLF_enable(BLF_ASPECT).
By default all the code that don't have BLF_ASPECT enable work with
a scale of 1.0 (so nothing change to the current UI).
I also remove all the call of BLF_aspect(fontid, 1.0) found in
the editors, because is disable by default, so no need any more.
Campbell the only thing to check is the python api, right now
I modify the api to from:
BLF_aspect(fontid, aspect)
to:
BLF_aspect(fontid, aspect, aspect, 1.0)
This is to avoid break the api, but now you need add the BLF_ASPECT
option to the function py_blf_enable and in some point change
py_blf_aspect to take 3 arguments.
2010-12-09 22:27:55 +00:00
|
|
|
BLF_aspect(fontid, aspect, aspect, 1.0);
|
2010-02-28 11:18:54 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_color_doc,
|
|
|
|
|
".. function:: color(fontid, r, g, b, a)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the color 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 r: red channel 0.0 - 1.0.\n"
|
|
|
|
|
" :type r: float\n"
|
|
|
|
|
" :arg g: green channel 0.0 - 1.0.\n"
|
|
|
|
|
" :type g: float\n"
|
|
|
|
|
" :arg b: blue channel 0.0 - 1.0.\n"
|
|
|
|
|
" :type b: float\n"
|
|
|
|
|
" :arg a: alpha channel 0.0 - 1.0.\n"
|
|
|
|
|
" :type a: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_color(PyObject * /*self*/, PyObject *args)
|
2018-06-21 13:01:24 +02:00
|
|
|
{
|
|
|
|
|
int fontid;
|
|
|
|
|
float rgba[4];
|
|
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "iffff:blf.color", &fontid, &rgba[0], &rgba[1], &rgba[2], &rgba[3]))
|
|
|
|
|
{
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2018-06-21 13:01:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLF_color4fv(fontid, rgba);
|
|
|
|
|
|
2025-03-15 08:58:50 +11:00
|
|
|
/* NOTE(@ideasman42): that storing these colors separately looks like something that could
|
|
|
|
|
* be refactored away if the font's internal color format was changed from `uint8` to `float`. */
|
|
|
|
|
BLF_buffer_col(fontid, rgba);
|
|
|
|
|
|
2018-06-21 13:01:24 +02:00
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_draw_doc,
|
|
|
|
|
".. function:: draw(fontid, text)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Draw text in the current context.\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 text: the text to draw.\n"
|
2024-11-03 15:42:19 +11:00
|
|
|
" :type text: str\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_draw(PyObject * /*self*/, PyObject *args)
|
2010-02-28 11:18:54 +00:00
|
|
|
{
|
2014-04-27 00:21:23 +10:00
|
|
|
const char *text;
|
2019-10-16 15:55:47 +11:00
|
|
|
Py_ssize_t text_length;
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int fontid;
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "is#:blf.draw", &fontid, &text, &text_length)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-02-28 11:18:54 +00:00
|
|
|
|
2023-07-22 11:33:36 +10:00
|
|
|
BLF_draw(fontid, text, uint(text_length));
|
2010-02-28 11:18:54 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-15 08:58:50 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_draw_buffer_doc,
|
|
|
|
|
".. function:: draw_buffer(fontid, text)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Draw text into the buffer bound to the fontid.\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 text: the text to draw.\n"
|
|
|
|
|
" :type text: str\n");
|
|
|
|
|
static PyObject *py_blf_draw_buffer(PyObject * /*self*/, PyObject *args)
|
|
|
|
|
{
|
|
|
|
|
const char *text;
|
|
|
|
|
Py_ssize_t text_length;
|
|
|
|
|
int fontid;
|
|
|
|
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "is#:blf.draw_buffer", &fontid, &text, &text_length)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLF_draw_buffer(fontid, text, uint(text_length));
|
|
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_dimensions_doc,
|
|
|
|
|
".. function:: dimensions(fontid, text)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Return the width and height of the 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 text: the text to draw.\n"
|
2024-11-03 15:42:19 +11:00
|
|
|
" :type text: str\n"
|
2024-01-25 10:22:16 +11:00
|
|
|
" :return: the width and height of the text.\n"
|
2024-11-03 15:42:19 +11:00
|
|
|
" :rtype: tuple[float, float]\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_dimensions(PyObject * /*self*/, PyObject *args)
|
2010-02-28 11:18:54 +00:00
|
|
|
{
|
2014-04-27 00:21:23 +10:00
|
|
|
const char *text;
|
2010-02-28 11:18:54 +00:00
|
|
|
float r_width, r_height;
|
|
|
|
|
PyObject *ret;
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int fontid;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "is:blf.dimensions", &fontid, &text)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-02 20:33:45 +11:00
|
|
|
BLF_width_and_height(fontid, text, INT_MAX, &r_width, &r_height);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-16 21:39:56 +00:00
|
|
|
ret = PyTuple_New(2);
|
2015-01-06 16:42:22 +11:00
|
|
|
PyTuple_SET_ITEMS(ret, PyFloat_FromDouble(r_width), PyFloat_FromDouble(r_height));
|
2010-02-28 11:18:54 +00:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_clipping_doc,
|
|
|
|
|
".. function:: clipping(fontid, xmin, ymin, xmax, ymax)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the clipping, enable/disable using CLIPPING.\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 xmin: Clip the drawing area by these bounds.\n"
|
|
|
|
|
" :type xmin: float\n"
|
|
|
|
|
" :arg ymin: Clip the drawing area by these bounds.\n"
|
|
|
|
|
" :type ymin: float\n"
|
|
|
|
|
" :arg xmax: Clip the drawing area by these bounds.\n"
|
|
|
|
|
" :type xmax: float\n"
|
|
|
|
|
" :arg ymax: Clip the drawing area by these bounds.\n"
|
|
|
|
|
" :type ymax: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_clipping(PyObject * /*self*/, PyObject *args)
|
2010-04-04 13:05:38 +00:00
|
|
|
{
|
|
|
|
|
float xmin, ymin, xmax, ymax;
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int fontid;
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "iffff:blf.clipping", &fontid, &xmin, &ymin, &xmax, &ymax)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-04-04 13:05:38 +00:00
|
|
|
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
BLF_clipping(fontid, xmin, ymin, xmax, ymax);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_word_wrap_doc,
|
|
|
|
|
".. function:: word_wrap(fontid, wrap_width)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the wrap width, enable/disable using WORD_WRAP.\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 wrap_width: The width (in pixels) to wrap words at.\n"
|
|
|
|
|
" :type wrap_width: int\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_word_wrap(PyObject * /*self*/, PyObject *args)
|
2015-09-18 20:10:26 +10:00
|
|
|
{
|
|
|
|
|
int wrap_width;
|
|
|
|
|
int fontid;
|
|
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "ii:blf.word_wrap", &fontid, &wrap_width)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2015-09-18 20:10:26 +10:00
|
|
|
|
|
|
|
|
BLF_wordwrap(fontid, wrap_width);
|
|
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_disable_doc,
|
|
|
|
|
".. function:: disable(fontid, option)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Disable option.\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 option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
|
|
|
|
|
" :type option: int\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_disable(PyObject * /*self*/, PyObject *args)
|
2010-04-04 13:05:38 +00:00
|
|
|
{
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int option, fontid;
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "ii:blf.disable", &fontid, &option)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-04-04 13:05:38 +00:00
|
|
|
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
BLF_disable(fontid, option);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_enable_doc,
|
|
|
|
|
".. function:: enable(fontid, option)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Enable option.\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 option: One of ROTATION, CLIPPING, SHADOW or KERNING_DEFAULT.\n"
|
|
|
|
|
" :type option: int\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_enable(PyObject * /*self*/, PyObject *args)
|
2010-04-04 13:05:38 +00:00
|
|
|
{
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int option, fontid;
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "ii:blf.enable", &fontid, &option)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-04-04 13:05:38 +00:00
|
|
|
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
BLF_enable(fontid, option);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_rotation_doc,
|
|
|
|
|
".. function:: rotation(fontid, angle)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the text rotation angle, enable/disable using ROTATION.\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 angle: The angle for text drawing to use.\n"
|
|
|
|
|
" :type angle: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_rotation(PyObject * /*self*/, PyObject *args)
|
2010-04-04 13:05:38 +00:00
|
|
|
{
|
|
|
|
|
float angle;
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int fontid;
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "if:blf.rotation", &fontid, &angle)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2018-06-04 08:54:17 +02:00
|
|
|
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
BLF_rotation(fontid, angle);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_shadow_doc,
|
|
|
|
|
".. function:: shadow(fontid, level, r, g, b, a)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Shadow options, enable/disable using SHADOW .\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"
|
UI: Improved overlay text contrast with new outline text decoration
Overlay texts were previously drawn with two sets of shadows:
- 3px blur,
- 5px blur, slightly offset
But since the shadow color was always set to black, it was still
causing legibility issues when the text itself was dark (set
via theme for example).
This PR adds a new "outline" BLF text decoration, and uses that
for the overlays. And it picks text/outline color depending
on the "background" color of the view.
Details:
- Instead of "shadow level" integer where the only valid options
are 0, 3 or 5, have a FontShadowType enum.
- Add a new FontShadowType::Outline enum entry, that does a 1px
outline by doing a 3x3 dilation in the font shader.
- BLF_draw_default_shadowed is changed to do outline, instead of
drawing the shadow twice.
- In the font shader, instead of encoding shadow type in signs of
the glyph_size, pass that as a "flags" vertex attribute. Put
font texture channel count into the same flags, so that the
vertex size stays the same.
- Well actually, vertex size becomes smaller by 4 bytes, since turns
out glyph_mode vertex attribute was not used for anything at all.
Images in the PR.
Co-authored-by: Harley Acheson <harley.acheson@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/121383
2024-05-10 21:06:44 +02:00
|
|
|
" :arg level: The blur level (0, 3, 5) or outline (6).\n"
|
2024-01-25 10:22:16 +11:00
|
|
|
" :type level: int\n"
|
|
|
|
|
" :arg r: Shadow color (red channel 0.0 - 1.0).\n"
|
|
|
|
|
" :type r: float\n"
|
|
|
|
|
" :arg g: Shadow color (green channel 0.0 - 1.0).\n"
|
|
|
|
|
" :type g: float\n"
|
|
|
|
|
" :arg b: Shadow color (blue channel 0.0 - 1.0).\n"
|
|
|
|
|
" :type b: float\n"
|
|
|
|
|
" :arg a: Shadow color (alpha channel 0.0 - 1.0).\n"
|
|
|
|
|
" :type a: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_shadow(PyObject * /*self*/, PyObject *args)
|
2010-04-04 13:05:38 +00:00
|
|
|
{
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int level, fontid;
|
2016-04-22 20:02:03 +10:00
|
|
|
float rgba[4];
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2016-04-22 20:02:03 +10:00
|
|
|
if (!PyArg_ParseTuple(
|
|
|
|
|
args, "iiffff:blf.shadow", &fontid, &level, &rgba[0], &rgba[1], &rgba[2], &rgba[3]))
|
|
|
|
|
{
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2016-04-22 20:02:03 +10:00
|
|
|
}
|
2010-04-04 13:05:38 +00:00
|
|
|
|
UI: Improved overlay text contrast with new outline text decoration
Overlay texts were previously drawn with two sets of shadows:
- 3px blur,
- 5px blur, slightly offset
But since the shadow color was always set to black, it was still
causing legibility issues when the text itself was dark (set
via theme for example).
This PR adds a new "outline" BLF text decoration, and uses that
for the overlays. And it picks text/outline color depending
on the "background" color of the view.
Details:
- Instead of "shadow level" integer where the only valid options
are 0, 3 or 5, have a FontShadowType enum.
- Add a new FontShadowType::Outline enum entry, that does a 1px
outline by doing a 3x3 dilation in the font shader.
- BLF_draw_default_shadowed is changed to do outline, instead of
drawing the shadow twice.
- In the font shader, instead of encoding shadow type in signs of
the glyph_size, pass that as a "flags" vertex attribute. Put
font texture channel count into the same flags, so that the
vertex size stays the same.
- Well actually, vertex size becomes smaller by 4 bytes, since turns
out glyph_mode vertex attribute was not used for anything at all.
Images in the PR.
Co-authored-by: Harley Acheson <harley.acheson@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/121383
2024-05-10 21:06:44 +02:00
|
|
|
if (!ELEM(level, 0, 3, 5, 6)) {
|
|
|
|
|
PyErr_SetString(PyExc_TypeError, "blf.shadow expected arg to be in (0, 3, 5, 6)");
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2010-04-04 13:05:38 +00:00
|
|
|
}
|
|
|
|
|
|
UI: Improved overlay text contrast with new outline text decoration
Overlay texts were previously drawn with two sets of shadows:
- 3px blur,
- 5px blur, slightly offset
But since the shadow color was always set to black, it was still
causing legibility issues when the text itself was dark (set
via theme for example).
This PR adds a new "outline" BLF text decoration, and uses that
for the overlays. And it picks text/outline color depending
on the "background" color of the view.
Details:
- Instead of "shadow level" integer where the only valid options
are 0, 3 or 5, have a FontShadowType enum.
- Add a new FontShadowType::Outline enum entry, that does a 1px
outline by doing a 3x3 dilation in the font shader.
- BLF_draw_default_shadowed is changed to do outline, instead of
drawing the shadow twice.
- In the font shader, instead of encoding shadow type in signs of
the glyph_size, pass that as a "flags" vertex attribute. Put
font texture channel count into the same flags, so that the
vertex size stays the same.
- Well actually, vertex size becomes smaller by 4 bytes, since turns
out glyph_mode vertex attribute was not used for anything at all.
Images in the PR.
Co-authored-by: Harley Acheson <harley.acheson@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/121383
2024-05-10 21:06:44 +02:00
|
|
|
BLF_shadow(fontid, FontShadowType(level), rgba);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_shadow_offset_doc,
|
|
|
|
|
".. function:: shadow_offset(fontid, x, y)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Set the offset for shadow 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: Vertical shadow offset value in pixels.\n"
|
|
|
|
|
" :type x: float\n"
|
|
|
|
|
" :arg y: Horizontal shadow offset value in pixels.\n"
|
|
|
|
|
" :type y: float\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_shadow_offset(PyObject * /*self*/, PyObject *args)
|
2010-04-04 13:05:38 +00:00
|
|
|
{
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
int x, y, fontid;
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2019-03-30 06:12:48 +11:00
|
|
|
if (!PyArg_ParseTuple(args, "iii:blf.shadow_offset", &fontid, &x, &y)) {
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2010-04-04 13:05:38 +00:00
|
|
|
|
BugFix:
[#20854] PROPERTIES STAMP: Rendering stamp flickers in output renders
Blenfont was not thread safe, that is why one thread can change
the font properties (size, dpi, color, etc) at the same time
that the stamp draw on the image, and then the problem.
To make blenfont thread safe I have to change two important things:
1) Every BLF_* function take one argument, the font id.
2) We have two new function to make font "thread safe":
BLF_load_unique
BLF_load_mem_unique
This two function are for case like stamp, that need and own font
that don't share the glyph cache, so can draw without problem
in a different thread.
Why the BLF_*_unique function ?
Because blenfont keep only one copy of a font and keep a list of
"glyph cache". Every glyph cache have size and dpi, so if two
different thread access the same font at the same time, they can
change value and finish with something like the stamp problem.
Why don't remove the glyph cache ?
Because if we do that, we finish with a font object for every size
and dpi, and the stamp is really a special case that happen in
the rendering process, so I really thing is better keep the
glyph cache and make this two new function to handle this
special case.
(When I say "font object" I mean have the same freetype font multiple
times just to have differents size and dpi)
As Matt point we still can have one case that two thread access
the BLF_*_unique function at the same time, but I am looking to
fix this with some class of thread lock.
For now I test and work fine, so if some one found problem, please
let me know.
Campbell I have to change the python api (python/generic/blf_api.c)
to the new syntax, so maybe you can take a look at this.
2010-04-22 10:56:45 +00:00
|
|
|
BLF_shadow_offset(fontid, x, y);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_load_doc,
|
|
|
|
|
".. function:: load(filepath)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Load a new font.\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" :arg filepath: the filepath of the font.\n"
|
2024-11-03 15:42:19 +11:00
|
|
|
" :type filepath: str | bytes\n"
|
2024-01-25 10:22:16 +11:00
|
|
|
" :return: the new font's fontid or -1 if there was an error.\n"
|
2024-11-03 15:42:19 +11:00
|
|
|
" :rtype: int\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_load(PyObject * /*self*/, PyObject *args)
|
2010-05-05 06:38:49 +00:00
|
|
|
{
|
2023-08-11 14:59:55 +10:00
|
|
|
PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
|
|
|
|
|
if (!PyArg_ParseTuple(args,
|
|
|
|
|
"O&" /* `filepath` */
|
|
|
|
|
":blf.load",
|
|
|
|
|
PyC_ParseUnicodeAsBytesAndSize,
|
|
|
|
|
&filepath_data))
|
|
|
|
|
{
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2023-08-11 14:59:55 +10:00
|
|
|
const int font_id = BLF_load(filepath_data.value);
|
|
|
|
|
Py_XDECREF(filepath_data.value_coerce);
|
2010-05-05 06:38:49 +00:00
|
|
|
|
2023-08-11 14:59:55 +10:00
|
|
|
return PyLong_FromLong(font_id);
|
2010-05-05 06:38:49 +00:00
|
|
|
}
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_unload_doc,
|
|
|
|
|
".. function:: unload(filepath)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Unload an existing font.\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" :arg filepath: the filepath of the font.\n"
|
2024-11-03 15:42:19 +11:00
|
|
|
" :type filepath: str | bytes\n");
|
2023-07-21 19:41:03 +02:00
|
|
|
static PyObject *py_blf_unload(PyObject * /*self*/, PyObject *args)
|
2011-05-30 11:03:16 +00:00
|
|
|
{
|
2023-08-11 14:59:55 +10:00
|
|
|
PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
|
|
|
|
|
if (!PyArg_ParseTuple(args,
|
|
|
|
|
"O&" /* `filepath` */
|
|
|
|
|
":blf.unload",
|
|
|
|
|
PyC_ParseUnicodeAsBytesAndSize,
|
|
|
|
|
&filepath_data))
|
|
|
|
|
{
|
2023-07-21 19:41:03 +02:00
|
|
|
return nullptr;
|
2019-03-30 06:12:48 +11:00
|
|
|
}
|
2011-09-21 16:06:47 +00:00
|
|
|
|
2023-08-11 14:59:55 +10:00
|
|
|
BLF_unload(filepath_data.value);
|
|
|
|
|
Py_XDECREF(filepath_data.value_coerce);
|
2011-09-21 16:06:47 +00:00
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
2011-05-30 11:03:16 +00:00
|
|
|
}
|
2011-06-20 10:07:46 +00:00
|
|
|
|
2025-03-15 08:58:50 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Image Buffer Access
|
|
|
|
|
*
|
|
|
|
|
* Context manager for #ImBuf.
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static PyObject *py_blf_bind_imbuf_enter(BPyBLFImBufContext *self)
|
|
|
|
|
{
|
|
|
|
|
if (UNLIKELY(self->buffer_state)) {
|
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
|
"BLFImBufContext.__enter__: unable to enter the same context more than once");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImBuf *ibuf = BPy_ImBuf_FromPyObject(self->py_imbuf);
|
|
|
|
|
if (ibuf == nullptr) {
|
|
|
|
|
/* The error will have been set. */
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
BLFBufferState *buffer_state = BLF_buffer_state_push(self->fontid);
|
|
|
|
|
if (buffer_state == nullptr) {
|
|
|
|
|
PyErr_Format(PyExc_ValueError, "bind_imbuf: unknown fontid %d", self->fontid);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
BLF_buffer(self->fontid,
|
|
|
|
|
ibuf->float_buffer.data,
|
|
|
|
|
ibuf->byte_buffer.data,
|
|
|
|
|
ibuf->x,
|
|
|
|
|
ibuf->y,
|
|
|
|
|
self->display);
|
|
|
|
|
self->buffer_state = buffer_state;
|
|
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PyObject *py_blf_bind_imbuf_exit(BPyBLFImBufContext *self, PyObject * /*args*/)
|
|
|
|
|
{
|
|
|
|
|
BLF_buffer_state_pop(self->buffer_state);
|
|
|
|
|
self->buffer_state = nullptr;
|
|
|
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void py_blf_bind_imbuf_dealloc(BPyBLFImBufContext *self)
|
|
|
|
|
{
|
|
|
|
|
if (self->buffer_state) {
|
|
|
|
|
/* This should practically never happen since it implies
|
|
|
|
|
* `__enter__` is called without a matching `__exit__`.
|
|
|
|
|
* Do this mainly for correctness:
|
|
|
|
|
* if the process somehow exits before exiting the context manager. */
|
|
|
|
|
BLF_buffer_state_free(self->buffer_state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PyObject_GC_UnTrack(self);
|
|
|
|
|
Py_CLEAR(self->py_imbuf);
|
|
|
|
|
PyObject_GC_Del(self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int py_blf_bind_imbuf_traverse(BPyBLFImBufContext *self, visitproc visit, void *arg)
|
|
|
|
|
{
|
|
|
|
|
Py_VISIT(self->py_imbuf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int py_blf_bind_imbuf_clear(BPyBLFImBufContext *self)
|
|
|
|
|
{
|
|
|
|
|
Py_CLEAR(self->py_imbuf);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-01 12:06:03 +11:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
# ifdef __clang__
|
|
|
|
|
# pragma clang diagnostic push
|
|
|
|
|
# pragma clang diagnostic ignored "-Wcast-function-type"
|
|
|
|
|
# else
|
|
|
|
|
# pragma GCC diagnostic push
|
|
|
|
|
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
|
|
|
|
# endif
|
2025-03-15 08:58:50 +11:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static PyMethodDef py_blf_bind_imbuf_methods[] = {
|
|
|
|
|
{"__enter__", (PyCFunction)py_blf_bind_imbuf_enter, METH_NOARGS},
|
|
|
|
|
{"__exit__", (PyCFunction)py_blf_bind_imbuf_exit, METH_VARARGS},
|
|
|
|
|
{nullptr},
|
|
|
|
|
};
|
|
|
|
|
|
2025-04-01 12:06:03 +11:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
# ifdef __clang__
|
|
|
|
|
# pragma clang diagnostic pop
|
|
|
|
|
# else
|
|
|
|
|
# pragma GCC diagnostic pop
|
|
|
|
|
# endif
|
2025-03-15 08:58:50 +11:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static PyTypeObject BPyBLFImBufContext_Type = {
|
|
|
|
|
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
|
|
|
|
/*tp_name*/ "BLFImBufContext",
|
|
|
|
|
/*tp_basicsize*/ sizeof(BPyBLFImBufContext),
|
|
|
|
|
/*tp_itemsize*/ 0,
|
|
|
|
|
/*tp_dealloc*/ (destructor)py_blf_bind_imbuf_dealloc,
|
|
|
|
|
/*tp_vectorcall_offset*/ 0,
|
|
|
|
|
/*tp_getattr*/ nullptr,
|
|
|
|
|
/*tp_setattr*/ nullptr,
|
|
|
|
|
/*tp_as_async*/ nullptr,
|
|
|
|
|
/*tp_repr*/ nullptr,
|
|
|
|
|
/*tp_as_number*/ nullptr,
|
|
|
|
|
/*tp_as_sequence*/ nullptr,
|
|
|
|
|
/*tp_as_mapping*/ nullptr,
|
|
|
|
|
/*tp_hash*/ nullptr,
|
|
|
|
|
/*tp_call*/ nullptr,
|
|
|
|
|
/*tp_str*/ nullptr,
|
|
|
|
|
/*tp_getattro*/ nullptr,
|
|
|
|
|
/*tp_setattro*/ nullptr,
|
|
|
|
|
/*tp_as_buffer*/ nullptr,
|
|
|
|
|
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
|
|
|
|
|
/*tp_doc*/ nullptr,
|
|
|
|
|
/*tp_traverse*/ (traverseproc)py_blf_bind_imbuf_traverse,
|
|
|
|
|
/*tp_clear*/ (inquiry)py_blf_bind_imbuf_clear,
|
|
|
|
|
/*tp_richcompare*/ nullptr,
|
|
|
|
|
/*tp_weaklistoffset*/ 0,
|
|
|
|
|
/*tp_iter*/ nullptr,
|
|
|
|
|
/*tp_iternext*/ nullptr,
|
|
|
|
|
/*tp_methods*/ py_blf_bind_imbuf_methods,
|
|
|
|
|
/*tp_members*/ nullptr,
|
|
|
|
|
/*tp_getset*/ nullptr,
|
|
|
|
|
/*tp_base*/ nullptr,
|
|
|
|
|
/*tp_dict*/ nullptr,
|
|
|
|
|
/*tp_descr_get*/ nullptr,
|
|
|
|
|
/*tp_descr_set*/ nullptr,
|
|
|
|
|
/*tp_dictoffset*/ 0,
|
|
|
|
|
/*tp_init*/ nullptr,
|
|
|
|
|
/*tp_alloc*/ nullptr,
|
|
|
|
|
/*tp_new*/ nullptr,
|
|
|
|
|
/*tp_free*/ nullptr,
|
|
|
|
|
/*tp_is_gc*/ nullptr,
|
|
|
|
|
/*tp_bases*/ nullptr,
|
|
|
|
|
/*tp_mro*/ nullptr,
|
|
|
|
|
/*tp_cache*/ nullptr,
|
|
|
|
|
/*tp_subclasses*/ nullptr,
|
|
|
|
|
/*tp_weaklist*/ nullptr,
|
|
|
|
|
/*tp_del*/ nullptr,
|
|
|
|
|
/*tp_version_tag*/ 0,
|
|
|
|
|
/*tp_finalize*/ nullptr,
|
|
|
|
|
/*tp_vectorcall*/ nullptr,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* NOTE(@ideasman42): `BLFImBufContext` isn't accessible from (without creating an instance),
|
|
|
|
|
* it should be exposed although it doesn't seem especially important either. */
|
|
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
py_blf_bind_imbuf_doc,
|
|
|
|
|
".. method:: bind_imbuf(fontid, image, display_name=None)\n"
|
|
|
|
|
"\n"
|
|
|
|
|
" Context manager to draw text into an image buffer instead of the GPU's context.\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 imbuf: The image to draw into.\n"
|
|
|
|
|
" :type imbuf: :class:`imbuf.types.ImBuf`\n"
|
|
|
|
|
" :arg display_name: The color management display name to use or None.\n"
|
|
|
|
|
" :type display_name: str | None\n"
|
|
|
|
|
|
|
|
|
|
" :return: The BLF ImBuf context manager.\n"
|
|
|
|
|
" :rtype: BLFImBufContext\n");
|
|
|
|
|
static PyObject *py_blf_bind_imbuf(PyObject * /*self*/, PyObject *args, PyObject *kwds)
|
|
|
|
|
{
|
|
|
|
|
int fontid;
|
|
|
|
|
PyObject *py_imbuf = nullptr;
|
|
|
|
|
const char *display_name = nullptr;
|
|
|
|
|
|
|
|
|
|
static const char *_keywords[] = {
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
"display_name",
|
|
|
|
|
nullptr,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static _PyArg_Parser _parser = {
|
|
|
|
|
PY_ARG_PARSER_HEAD_COMPAT()
|
|
|
|
|
"i" /* `fontid` */
|
|
|
|
|
"O!" /* `image` */
|
|
|
|
|
"|" /* Optional arguments. */
|
|
|
|
|
"z" /* `display_name` */
|
|
|
|
|
":bind_imbuf",
|
|
|
|
|
_keywords,
|
|
|
|
|
nullptr,
|
|
|
|
|
};
|
|
|
|
|
if (!_PyArg_ParseTupleAndKeywordsFast(
|
|
|
|
|
args, kwds, &_parser, &fontid, &Py_ImBuf_Type, &py_imbuf, &display_name))
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
Refactor: OpenColorIO integration
Briefly about this change:
- OpenColorIO C-API is removed.
- The information about color spaces in ImBuf module is removed.
It was stored in global ListBase in colormanagement.cc.
- Both OpenColorIO and fallback implementation supports GPU drawing.
- Fallback implementation supports white point, RGB curves, etc.
- Removed check for support of GPU drawing in IMB.
Historically it was implemented in a separate library with C-API, this
is because way back C++ code needed to stay in intern. This causes all
sort of overheads, and even calls that are strictly considered bad
level.
This change moves OpenColorIO integration into a module within imbuf,
next to movie, and next to IMB_colormanagement which is the main user
of it. This allows to avoid copy of color spaces, displays, views etc
in the ImBuf: they were used to help quickly querying information to
be shown on the interface. With this change it can be stored in the
same data structures as what is used by the OpenColorIO integration.
While it might not be fully avoiding duplication it is now less, and
there is no need in the user code to maintain the copies.
In a lot of cases this change also avoids allocations done per access
to the OpenColorIO. For example, it is not needed anymore to allocate
image descriptor in a heap.
The bigger user-visible change is that the fallback implementation now
supports GLSL drawing, with the whole list of supported features, such
as curve mapping and white point. This should help simplifying code
which relies on color space conversion on GPU: there is no need to
figure out fallback solution in such cases. The only case when drawing
will not work is when there is some actual bug, or driver issue, and
shader has failed to compile.
The change avoids having an opaque type for color space, and instead
uses forward declaration. It is a bit verbose on declaration, but helps
avoiding unsafe type-casts. There are ways to solve this in the future,
like having a header for forward declaration, or to flatten the name
space a bit.
There should be no user-level changes under normal operation.
When building without OpenColorIO or the configuration has a typo or
is missing a fuller set of color management tools is applies (such as the
white point correction).
Pull Request: https://projects.blender.org/blender/blender/pulls/138433
2025-05-09 14:01:43 +02:00
|
|
|
const ColorManagedDisplay *display = nullptr;
|
2025-03-15 08:58:50 +11:00
|
|
|
if (display_name) {
|
|
|
|
|
display = IMB_colormanagement_display_get_named(display_name);
|
|
|
|
|
if (UNLIKELY(display == nullptr)) {
|
|
|
|
|
std::string display_names_all;
|
|
|
|
|
display_names_all.reserve(1024);
|
|
|
|
|
const char *ex = nullptr;
|
|
|
|
|
/* 1 based index. */
|
|
|
|
|
for (int i = 1; (ex = IMB_colormanagement_display_get_indexed_name(i)); i++) {
|
|
|
|
|
if (i > 1) {
|
|
|
|
|
display_names_all += ", ";
|
|
|
|
|
}
|
|
|
|
|
display_names_all += ex;
|
|
|
|
|
}
|
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
|
"bind_imbuf: color management \"%s\" not found in [%s]",
|
|
|
|
|
display_name,
|
|
|
|
|
display_names_all.c_str());
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BPyBLFImBufContext *ret = PyObject_GC_New(BPyBLFImBufContext, &BPyBLFImBufContext_Type);
|
|
|
|
|
|
|
|
|
|
ret->py_imbuf = Py_NewRef(py_imbuf);
|
|
|
|
|
ret->display = display;
|
|
|
|
|
|
|
|
|
|
ret->fontid = fontid;
|
|
|
|
|
ret->buffer_state = nullptr;
|
|
|
|
|
|
|
|
|
|
PyObject_GC_Track(ret);
|
|
|
|
|
|
|
|
|
|
return (PyObject *)ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2025-04-01 12:06:03 +11:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
# ifdef __clang__
|
|
|
|
|
# pragma clang diagnostic push
|
|
|
|
|
# pragma clang diagnostic ignored "-Wcast-function-type"
|
|
|
|
|
# else
|
|
|
|
|
# pragma GCC diagnostic push
|
|
|
|
|
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-02-28 11:18:54 +00:00
|
|
|
/*----------------------------MODULE INIT-------------------------*/
|
2011-02-13 10:52:18 +00:00
|
|
|
static PyMethodDef BLF_methods[] = {
|
2010-02-28 11:18:54 +00:00
|
|
|
{"aspect", (PyCFunction)py_blf_aspect, METH_VARARGS, py_blf_aspect_doc},
|
2010-04-04 13:05:38 +00:00
|
|
|
{"clipping", (PyCFunction)py_blf_clipping, METH_VARARGS, py_blf_clipping_doc},
|
2015-09-18 20:10:26 +10:00
|
|
|
{"word_wrap", (PyCFunction)py_blf_word_wrap, METH_VARARGS, py_blf_word_wrap_doc},
|
2010-04-04 13:05:38 +00:00
|
|
|
{"disable", (PyCFunction)py_blf_disable, METH_VARARGS, py_blf_disable_doc},
|
2010-02-28 11:18:54 +00:00
|
|
|
{"dimensions", (PyCFunction)py_blf_dimensions, METH_VARARGS, py_blf_dimensions_doc},
|
2010-04-04 13:05:38 +00:00
|
|
|
{"draw", (PyCFunction)py_blf_draw, METH_VARARGS, py_blf_draw_doc},
|
2025-03-15 08:58:50 +11:00
|
|
|
{"draw_buffer", (PyCFunction)py_blf_draw_buffer, METH_VARARGS, py_blf_draw_buffer_doc},
|
2010-04-04 13:05:38 +00:00
|
|
|
{"enable", (PyCFunction)py_blf_enable, METH_VARARGS, py_blf_enable_doc},
|
2010-12-10 00:20:32 +00:00
|
|
|
{"position", (PyCFunction)py_blf_position, METH_VARARGS, py_blf_position_doc},
|
2010-04-04 13:05:38 +00:00
|
|
|
{"rotation", (PyCFunction)py_blf_rotation, METH_VARARGS, py_blf_rotation_doc},
|
|
|
|
|
{"shadow", (PyCFunction)py_blf_shadow, METH_VARARGS, py_blf_shadow_doc},
|
|
|
|
|
{"shadow_offset", (PyCFunction)py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc},
|
|
|
|
|
{"size", (PyCFunction)py_blf_size, METH_VARARGS, py_blf_size_doc},
|
2018-06-21 13:01:24 +02:00
|
|
|
{"color", (PyCFunction)py_blf_color, METH_VARARGS, py_blf_color_doc},
|
2010-05-05 06:38:49 +00:00
|
|
|
{"load", (PyCFunction)py_blf_load, METH_VARARGS, py_blf_load_doc},
|
2011-09-21 16:06:47 +00:00
|
|
|
{"unload", (PyCFunction)py_blf_unload, METH_VARARGS, py_blf_unload_doc},
|
2025-03-15 08:58:50 +11:00
|
|
|
|
|
|
|
|
{"bind_imbuf",
|
|
|
|
|
(PyCFunction)py_blf_bind_imbuf,
|
|
|
|
|
METH_VARARGS | METH_KEYWORDS,
|
|
|
|
|
py_blf_bind_imbuf_doc},
|
|
|
|
|
|
2023-07-21 19:41:03 +02:00
|
|
|
{nullptr, nullptr, 0, nullptr},
|
2010-02-28 11:18:54 +00:00
|
|
|
};
|
|
|
|
|
|
2025-04-01 12:06:03 +11:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
# ifdef __clang__
|
|
|
|
|
# pragma clang diagnostic pop
|
|
|
|
|
# else
|
|
|
|
|
# pragma GCC diagnostic pop
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-01-25 10:22:16 +11:00
|
|
|
PyDoc_STRVAR(
|
|
|
|
|
/* Wrap. */
|
|
|
|
|
BLF_doc,
|
|
|
|
|
"This module provides access to Blender's text drawing functions.");
|
2023-06-03 08:36:28 +10:00
|
|
|
static PyModuleDef BLF_module_def = {
|
2023-07-16 17:43:31 +10:00
|
|
|
/*m_base*/ PyModuleDef_HEAD_INIT,
|
2022-11-08 11:13:58 +11:00
|
|
|
/*m_name*/ "blf",
|
|
|
|
|
/*m_doc*/ BLF_doc,
|
|
|
|
|
/*m_size*/ 0,
|
|
|
|
|
/*m_methods*/ BLF_methods,
|
2023-07-21 19:41:03 +02:00
|
|
|
/*m_slots*/ nullptr,
|
|
|
|
|
/*m_traverse*/ nullptr,
|
|
|
|
|
/*m_clear*/ nullptr,
|
|
|
|
|
/*m_free*/ nullptr,
|
2010-02-28 11:18:54 +00:00
|
|
|
};
|
|
|
|
|
|
2023-07-22 11:33:36 +10:00
|
|
|
PyObject *BPyInit_blf()
|
2010-02-28 11:18:54 +00:00
|
|
|
{
|
|
|
|
|
PyObject *submodule;
|
|
|
|
|
|
|
|
|
|
submodule = PyModule_Create(&BLF_module_def);
|
|
|
|
|
|
2010-04-04 13:05:38 +00:00
|
|
|
PyModule_AddIntConstant(submodule, "ROTATION", BLF_ROTATION);
|
|
|
|
|
PyModule_AddIntConstant(submodule, "CLIPPING", BLF_CLIPPING);
|
|
|
|
|
PyModule_AddIntConstant(submodule, "SHADOW", BLF_SHADOW);
|
2015-09-18 20:10:26 +10:00
|
|
|
PyModule_AddIntConstant(submodule, "WORD_WRAP", BLF_WORD_WRAP);
|
2018-07-31 16:57:05 +10:00
|
|
|
PyModule_AddIntConstant(submodule, "MONOCHROME", BLF_MONOCHROME);
|
2010-04-04 13:05:38 +00:00
|
|
|
|
2010-10-29 22:59:39 +00:00
|
|
|
return submodule;
|
2010-05-29 21:31:57 +00:00
|
|
|
}
|