Skip to content

Commit

Permalink
Support SkFontArguments::Palette
Browse files Browse the repository at this point in the history
To allow selecting color fonts palette.
  • Loading branch information
khaledhosny committed Jan 3, 2025
1 parent db7d7fc commit 6e18951
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
75 changes: 75 additions & 0 deletions src/skia/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ sk_sp<SkFontMgr> SkFontMgr_RefDefault() {

using Axis = SkFontParameters::Variation::Axis;
using Coordinate = SkFontArguments::VariationPosition::Coordinate;
using Override = SkFontArguments::Palette::Override;
PYBIND11_MAKE_OPAQUE(std::vector<Coordinate>);
PYBIND11_MAKE_OPAQUE(std::vector<Override>);

namespace {

Expand All @@ -65,6 +67,12 @@ void SetVariationPositionCoordinates(
vp.coordinateCount = coords.size();
}

void SetPaletteOverrides(
SkFontArguments::Palette& palette,
const std::vector<Override>& overrides) {
palette.overrides = overrides.empty() ? nullptr : &overrides[0];
palette.overrideCount = overrides.size();
}

py::tuple SkFontStyleSet_getStyle(SkFontStyleSet* self, int index) {
SkFontStyle style;
Expand Down Expand Up @@ -342,6 +350,59 @@ variationposition
&SkFontArguments::VariationPosition::coordinateCount)
;

py::class_<SkFontArguments::Palette> palette(
fontarguments, "Palette",
R"docstring(
A a palette to use and overrides for palette entries.
)docstring");

py::class_<Override>(palette, "Override")
.def(py::init(
[] (uint16_t index, SkColor color) {
return Override({index, color});
}),
py::arg("index"), py::arg("color"))
.def("__repr__",
[] (const Override& self) {
return py::str("Override(index={}, color={})").format(
self.index, self.color);
})
.def_readwrite("index", &Override::index)
.def_readwrite("color", &Override::color)
;

py::bind_vector<std::vector<Override>>(palette, "Overrides");

palette
.def(py::init(
[] (int index, const std::vector<Override>& overrides) {
SkFontArguments::Palette palette;
palette.index = index;
SetPaletteOverrides(palette, overrides);
return palette;
}),
py::keep_alive<1, 3>(),
py::arg("index"), py::arg("overrides"))
.def(py::init(
[] (int index) {
return SkFontArguments::Palette({index, nullptr, 0});
}),
py::arg("index"))
.def("__repr__",
[] (const SkFontArguments::Palette& self) {
return py::str("Palette(index={}, overrideCount={})").format(
self.index, self.overrideCount);
})
.def_property("overrides",
[] (const SkFontArguments::Palette& self) {
return std::vector<Override>(
self.overrides, self.overrides + self.overrideCount);
},
&SetPaletteOverrides)
.def_readwrite("index", &SkFontArguments::Palette::index)
.def_readonly("overrideCount", &SkFontArguments::Palette::overrideCount)
;

fontarguments
.def(py::init<>())
.def("setCollectionIndex", &SkFontArguments::setCollectionIndex,
Expand All @@ -352,6 +413,19 @@ fontarguments
actually be indexed collections of fonts.
)docstring",
py::arg("collectionIndex"))
.def("setPalette", &SkFontArguments::setPalette,
R"docstring(
Specify a palette to use and overrides for palette entries.
)docstring",
py::arg("palette"))
.def("setPalette",
[](SkFontArguments& self, int index) {
return self.setPalette(SkFontArguments::Palette({index, nullptr, 0}));
},
R"docstring(
Specify a palette index to use.
)docstring",
py::arg("index"))
.def("setVariationDesignPosition",
&SkFontArguments::setVariationDesignPosition,
R"docstring(
Expand All @@ -365,6 +439,7 @@ fontarguments
)docstring",
py::arg("position"))
.def("getCollectionIndex", &SkFontArguments::getCollectionIndex)
.def("getPalette", &SkFontArguments::getPalette)
.def("getVariationDesignPosition",
&SkFontArguments::getVariationDesignPosition)
;
Expand Down
42 changes: 42 additions & 0 deletions tests/test_font.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,44 @@ def test_FontArguments_setCollectionIndex(fontarguments):
fontarguments.setCollectionIndex(0)


@pytest.mark.parametrize(
"index, overrides",
[
(0, [(0, skia.ColorBLACK), (1, skia.ColorRED), (5, skia.ColorBLUE)]),
(1, []),
(2, None),
],
)
def test_FontArguments_setPalette(fontarguments, index, overrides):
if overrides is None:
palette = skia.FontArguments.Palette(index)
else:
palette = skia.FontArguments.Palette(
index,
skia.FontArguments.Palette.Overrides(
[
skia.FontArguments.Palette.Override(*override)
for override in overrides
]
),
)

len_overrides = len(overrides) if overrides is not None else 0
assert palette.index == index
assert len(palette.overrides) == len_overrides
assert palette.overrideCount == len_overrides
assert repr(palette) == f"Palette(index={index}, overrideCount={len_overrides})"
for i, override in enumerate(palette.overrides):
assert repr(override) == f"Override(index={override.index}, color={override.color})"
assert override.index == overrides[i][0]
assert override.color == overrides[i][1]
fontarguments.setPalette(palette)


def test_FontArguments_setPalette_Index(fontarguments):
fontarguments.setPalette(1)


def test_FontArguments_setVariationDesignPosition(fontarguments):
coordinates = skia.FontArguments.VariationPosition.Coordinates([
skia.FontArguments.VariationPosition.Coordinate(0x00, 0.),
Expand All @@ -58,6 +96,10 @@ def test_FontArguments_getCollectionIndex(fontarguments):
assert isinstance(fontarguments.getCollectionIndex(), int)


def test_FontArguments_getPalette(fontarguments):
assert isinstance(fontarguments.getPalette(), skia.FontArguments.Palette)


def test_FontArguments_getVariationDesignPosition(fontarguments):
assert isinstance(
fontarguments.getVariationDesignPosition(),
Expand Down

0 comments on commit 6e18951

Please sign in to comment.