Browse Source

python: expose new text.AbstractFont APIs.

And add a bounds check for glyph_advance() and the new glyph_size() too.
next
Vladimír Vondruš 3 years ago
parent
commit
8ca1c30187
  1. 8
      doc/python/magnum.text.rst
  2. 17
      src/python/magnum/test/test_text.py
  3. 15
      src/python/magnum/text.cpp

8
doc/python/magnum.text.rst

@ -73,9 +73,17 @@
:raise AssertionError: If no file is opened
.. py:property:: magnum.text.AbstractFont.line_height
:raise AssertionError: If no file is opened
.. py:property:: magnum.text.AbstractFont.glyph_count
:raise AssertionError: If no file is opened
.. py:function:: magnum.text.AbstractFont.glyph_id
:raise AssertionError: If no file is opened
.. py:function:: magnum.text.AbstractFont.glyph_size
:raise AssertionError: If no file is opened
:raise IndexError: If :p:`glyph` is negative or not less than
:ref:`glyph_count`
.. py:function:: magnum.text.AbstractFont.glyph_advance
:raise AssertionError: If no file is opened
:raise IndexError: If :p:`glyph` is negative or not less than
:ref:`glyph_count`
.. py:function:: magnum.text.AbstractFont.fill_glyph_cache
:raise AssertionError: If no file is opened

17
src/python/magnum/test/test_text.py

@ -57,8 +57,12 @@ class Font(unittest.TestCase):
font.descent
with self.assertRaisesRegex(AssertionError, "no file opened"):
font.line_height
with self.assertRaisesRegex(AssertionError, "no file opened"):
font.glyph_count
with self.assertRaisesRegex(AssertionError, "no file opened"):
font.glyph_id('A')
with self.assertRaisesRegex(AssertionError, "no file opened"):
font.glyph_size(0)
with self.assertRaisesRegex(AssertionError, "no file opened"):
font.glyph_advance(0)
# fill_glyph_cache() not tested as it needs a GL context; assuming it's
@ -88,7 +92,9 @@ class Font(unittest.TestCase):
self.assertEqual(font.ascent, 17.011186599731445)
self.assertEqual(font.descent, -4.322147846221924)
self.assertEqual(font.line_height, 21.33333396911621)
self.assertEqual(font.glyph_count, 671)
self.assertEqual(font.glyph_id('A'), 36)
self.assertEqual(font.glyph_size(36), (12.0, 14.0))
self.assertEqual(font.glyph_advance(36), (11.7136, 0.0))
# Deleting the font should decrease manager refcount again
@ -102,3 +108,14 @@ class Font(unittest.TestCase):
font.open_data(f.read(), 16.0)
self.assertEqual(font.size, 16.0)
def test_glyph_oob(self):
font = text.FontManager().load_and_instantiate('StbTrueTypeFont')
font.open_file(os.path.join(os.path.dirname(__file__), 'Oxygen.ttf'), 16.0)
self.assertEqual(font.glyph_count, 671)
with self.assertRaises(IndexError):
font.glyph_size(671)
with self.assertRaises(IndexError):
font.glyph_advance(671)

15
src/python/magnum/text.cpp

@ -60,6 +60,17 @@ template<class R, class Arg1, R(Text::AbstractFont::*f)(Arg1)> R checkOpened(Tex
}
return (self.*f)(arg1);
}
template<class R, R(Text::AbstractFont::*f)(UnsignedInt)> R checkOpenedBounds(Text::AbstractFont& self, UnsignedInt glyph) {
if(!self.isOpened()) {
PyErr_SetString(PyExc_AssertionError, "no file opened");
throw py::error_already_set{};
}
if(glyph >= self.glyphCount()) {
PyErr_SetNone(PyExc_IndexError);
throw py::error_already_set{};
}
return (self.*f)(glyph);
}
}
@ -136,8 +147,10 @@ void text(py::module_& m) {
.def_property_readonly("ascent", checkOpened<Float, &Text::AbstractFont::ascent>, "Font ascent")
.def_property_readonly("descent", checkOpened<Float, &Text::AbstractFont::descent>, "Font descent")
.def_property_readonly("line_height", checkOpened<Float, &Text::AbstractFont::lineHeight>, "Line height")
.def_property_readonly("glyph_count", checkOpened<UnsignedInt, &Text::AbstractFont::glyphCount>, "Total count of glyphs in the font")
.def("glyph_id", checkOpened<UnsignedInt, char32_t, &Text::AbstractFont::glyphId>, "Glyph ID for given character", py::arg("character"))
.def("glyph_advance", checkOpened<Vector2, UnsignedInt, &Text::AbstractFont::glyphAdvance>, "Glyph advance", py::arg("glyph"))
.def("glyph_size", checkOpenedBounds<Vector2, &Text::AbstractFont::glyphSize>, "Glyph size in pixels", py::arg("glyph"))
.def("glyph_advance", checkOpenedBounds<Vector2, &Text::AbstractFont::glyphAdvance>, "Glyph advance in pixels", py::arg("glyph"))
.def("fill_glyph_cache", [](Text::AbstractFont& self, Text::AbstractGlyphCache& cache, const std::string& characters) {
if(!self.isOpened()) {
PyErr_SetString(PyExc_AssertionError, "no file opened");

Loading…
Cancel
Save