summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/font/PhysicalFontFace.hxx14
-rw-r--r--vcl/source/font/PhysicalFontFace.cxx55
2 files changed, 69 insertions, 0 deletions
diff --git a/vcl/inc/font/PhysicalFontFace.hxx b/vcl/inc/font/PhysicalFontFace.hxx
index 01ad46dea54e..75133503e8af 100644
--- a/vcl/inc/font/PhysicalFontFace.hxx
+++ b/vcl/inc/font/PhysicalFontFace.hxx
@@ -23,6 +23,7 @@
#include <salhelper/simplereferenceobject.hxx>
#include <rtl/ref.hxx>
+#include <tools/color.hxx>
#include <tools/long.hxx>
#include <vcl/dllapi.h>
#include <vcl/fontcapabilities.hxx>
@@ -84,6 +85,14 @@ private:
hb_blob_t* mpBlob;
};
+struct ColorLayer
+{
+ sal_GlyphId nGlyphIndex;
+ uint32_t nColorIndex;
+};
+
+typedef std::vector<Color> ColorPalette;
+
// TODO: no more direct access to members
// TODO: get rid of height/width for scalable fonts
// TODO: make cloning cheaper
@@ -125,6 +134,10 @@ public:
bool CreateFontSubset(std::vector<sal_uInt8>&, const sal_GlyphId*, const sal_uInt8*, const int,
FontSubsetInfo&) const;
+ bool HasColorLayers() const;
+ const ColorPalette& GetColorPalette(size_t) const;
+ std::vector<ColorLayer> GetGlyphColorLayers(sal_GlyphId) const;
+
virtual hb_face_t* GetHbFace() const;
virtual hb_blob_t* GetHbTable(hb_tag_t) const
{
@@ -137,6 +150,7 @@ protected:
mutable FontCharMapRef mxCharMap;
mutable vcl::FontCapabilities maFontCapabilities;
mutable bool mbFontCapabilitiesRead;
+ mutable std::vector<ColorPalette> maColorPalettes;
explicit PhysicalFontFace(const FontAttributes&);
};
diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx
index 66cd3aae584b..4a459ae8cee3 100644
--- a/vcl/source/font/PhysicalFontFace.cxx
+++ b/vcl/source/font/PhysicalFontFace.cxx
@@ -36,6 +36,8 @@
#include <string_view>
+#include <hb-ot.h>
+
namespace vcl::font
{
PhysicalFontFace::PhysicalFontFace(const FontAttributes& rDFA)
@@ -305,6 +307,59 @@ bool PhysicalFontFace::CreateFontSubset(std::vector<sal_uInt8>& rOutBuffer,
// write subset into destination file
return CreateTTFfontSubset(aSftFont, rOutBuffer, pGlyphIds, pEncoding, nGlyphCount);
}
+
+bool PhysicalFontFace::HasColorLayers() const
+{
+ const auto pHbFace = GetHbFace();
+ return hb_ot_color_has_layers(pHbFace) && hb_ot_color_has_palettes(pHbFace);
+}
+
+const ColorPalette& PhysicalFontFace::GetColorPalette(size_t nIndex) const
+{
+ if (maColorPalettes.empty())
+ {
+ const auto pHbFace = GetHbFace();
+
+ auto nPalettes = hb_ot_color_palette_get_count(pHbFace);
+ maColorPalettes.reserve(nPalettes);
+ for (auto nPalette = 0u; nPalette < nPalettes; nPalette++)
+ {
+ auto nColors = hb_ot_color_palette_get_colors(pHbFace, nPalette, 0, nullptr, nullptr);
+ ColorPalette aPalette(nColors);
+ for (auto nColor = 0u; nColor < nColors; nColor++)
+ {
+ uint32_t nCount = 1;
+ hb_color_t aColor;
+ hb_ot_color_palette_get_colors(pHbFace, nPalette, nColor, &nCount, &aColor);
+ auto a = hb_color_get_alpha(aColor);
+ auto r = hb_color_get_red(aColor);
+ auto g = hb_color_get_green(aColor);
+ auto b = hb_color_get_blue(aColor);
+ aPalette[nColor] = Color(ColorAlphaTag::ColorAlpha, a, r, g, b);
+ }
+ maColorPalettes.push_back(aPalette);
+ }
+ }
+
+ return maColorPalettes[nIndex];
+}
+
+std::vector<ColorLayer> PhysicalFontFace::GetGlyphColorLayers(sal_GlyphId nGlyphIndex) const
+{
+ const auto pHbFace = GetHbFace();
+
+ auto nLayers = hb_ot_color_glyph_get_layers(pHbFace, nGlyphIndex, 0, nullptr, nullptr);
+ std::vector<ColorLayer> aLayers(nLayers);
+ for (auto nLayer = 0u; nLayer < nLayers; nLayer++)
+ {
+ hb_ot_color_layer_t aLayer;
+ uint32_t nCount = 1;
+ hb_ot_color_glyph_get_layers(pHbFace, nGlyphIndex, nLayer, &nCount, &aLayer);
+ aLayers[nLayer] = { aLayer.glyph, aLayer.color_index };
+ }
+
+ return aLayers;
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */