From 79baffbd34558d1a8fe451ed71421b0905d95edc Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Tue, 26 Sep 2023 08:29:04 +0200 Subject: [PATCH] Add font options custom palette color APIs Adds: * FontOptions.set_custom_palette_color * FontOptions.get_custom_palette_color See #309 --- cairo/__init__.pyi | 32 ++++++++++++++++++++++++++++++++ cairo/font.c | 30 ++++++++++++++++++++++++++++++ tests/test_font.py | 11 +++++++++++ 3 files changed, 73 insertions(+) diff --git a/cairo/__init__.pyi b/cairo/__init__.pyi index 53a50705..3b9ab4cd 100644 --- a/cairo/__init__.pyi +++ b/cairo/__init__.pyi @@ -1653,6 +1653,38 @@ class FontOptions: .. versionadded:: 1.25.0 Only available with cairo 1.17.8+ """ + def set_custom_palette_color(self, index: int, red: float, green: float, blue: float, alpha: float) -> None: + """ + :param index: the index of the color to set + :param red: red component of color + :param green: green component of color + :param blue: blue component of color + :param alpha: alpha component of color + + Sets a custom palette color for the font options object. This overrides + the palette color at the specified color index. This override is + independent of the selected palette index and will remain in place even + if :meth:`FontOptions.set_color_palette` is called to change the palette + index. + + It is only possible to override color indexes already in the font + palette. + + .. versionadded:: 1.25.0 Only available with cairo 1.17.8+ + """ + + def get_custom_palette_color(self, index: int) -> Tuple[float, float, float, float]: + """ + :param index: the index of the color to get + :returns: a (red, green, blue, alpha) tuple of float + :raises Error: if no custom color exists for the color index. + + Gets the custom palette color for the color index for the font options + object. + + .. versionadded:: 1.25.0 Only available with cairo 1.17.8+ + """ + class ScaledFont: """ A *ScaledFont* is a font scaled to a particular size and device resolution. A diff --git a/cairo/font.c b/cairo/font.c index 3a6b2a9b..f2833aa1 100644 --- a/cairo/font.c +++ b/cairo/font.c @@ -710,6 +710,34 @@ static PyObject * font_options_get_color_palette (PycairoFontOptions *o, PyObject *ignored) { return PyLong_FromUnsignedLong (cairo_font_options_get_color_palette (o->font_options)); } + +static PyObject * +font_options_set_custom_palette_color (PycairoFontOptions *o, PyObject *args) { + double red, green, blue, alpha; + unsigned int index; + + if (!PyArg_ParseTuple (args, "Idddd:FontOptions.set_custom_palette_color", + &index, &red, &green, &blue, &alpha)) + return NULL; + + cairo_font_options_set_custom_palette_color (o->font_options, index, red, green, blue, alpha); + RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); + Py_RETURN_NONE; +} + +static PyObject * +font_options_get_custom_palette_color (PycairoFontOptions *o, PyObject *args) { + double red, green, blue, alpha; + unsigned int index; + cairo_status_t status; + + if (!PyArg_ParseTuple (args, "I:FontOptions.get_custom_palette_color", &index)) + return NULL; + + status = cairo_font_options_get_custom_palette_color (o->font_options, index, &red, &green, &blue, &alpha); + RETURN_NULL_IF_CAIRO_ERROR (status); + return Py_BuildValue("(dddd)", red, green, blue, alpha); +} #endif static PyObject * @@ -865,6 +893,8 @@ static PyMethodDef font_options_methods[] = { {"set_color_mode", (PyCFunction)font_options_set_color_mode, METH_VARARGS}, {"get_color_palette", (PyCFunction)font_options_get_color_palette, METH_NOARGS}, {"set_color_palette", (PyCFunction)font_options_set_color_palette, METH_VARARGS}, + {"get_custom_palette_color", (PyCFunction)font_options_get_custom_palette_color, METH_VARARGS}, + {"set_custom_palette_color", (PyCFunction)font_options_set_custom_palette_color, METH_VARARGS}, #endif {"get_antialias", (PyCFunction)font_options_get_antialias, METH_NOARGS}, {"get_hint_metrics", (PyCFunction)font_options_get_hint_metrics, diff --git a/tests/test_font.py b/tests/test_font.py index d6fa40c7..e504a374 100644 --- a/tests/test_font.py +++ b/tests/test_font.py @@ -23,6 +23,17 @@ def scaled_font(font_face, font_options): font_face, cairo.Matrix(), cairo.Matrix(), font_options) +@pytest.mark.skipif(not hasattr(cairo.FontOptions, "set_custom_palette_color"), + reason="too old cairo") +def test_font_options_custom_palette_color(font_options): + font_options.set_custom_palette_color(42, 0.25, 0.5, 0.75, 1.0) + with pytest.raises(cairo.Error) as exc_info: + font_options.get_custom_palette_color(24) + assert exc_info.value.status == cairo.Status.INVALID_INDEX + assert font_options.get_custom_palette_color(42) == (0.25, 0.5, 0.75, 1.0) + assert isinstance(font_options.get_custom_palette_color(42), tuple) + + @pytest.mark.skipif(not hasattr(cairo.FontOptions, "set_color_mode"), reason="too old cairo") def test_font_options_set_color_mode(font_options):