diff --git a/doc/python/magnum.text.rst b/doc/python/magnum.text.rst index 7e511ed..bfeffa6 100644 --- a/doc/python/magnum.text.rst +++ b/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 diff --git a/src/python/magnum/test/test_text.py b/src/python/magnum/test/test_text.py index 0f2191c..43c37f8 100644 --- a/src/python/magnum/test/test_text.py +++ b/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) diff --git a/src/python/magnum/text.cpp b/src/python/magnum/text.cpp index 5d80bcf..da15ee4 100644 --- a/src/python/magnum/text.cpp +++ b/src/python/magnum/text.cpp @@ -60,6 +60,17 @@ template R checkOpened(Tex } return (self.*f)(arg1); } +template 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, "Font ascent") .def_property_readonly("descent", checkOpened, "Font descent") .def_property_readonly("line_height", checkOpened, "Line height") + .def_property_readonly("glyph_count", checkOpened, "Total count of glyphs in the font") .def("glyph_id", checkOpened, "Glyph ID for given character", py::arg("character")) - .def("glyph_advance", checkOpened, "Glyph advance", py::arg("glyph")) + .def("glyph_size", checkOpenedBounds, "Glyph size in pixels", py::arg("glyph")) + .def("glyph_advance", checkOpenedBounds, "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");