summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2018-05-01 23:03:46 +0200
committerKhaled Hosny <khaledhosny@eglug.org>2018-05-01 23:03:46 +0200
commitfa1ec9461e2f78655e9aa17473dba085b0b6015d (patch)
tree40d683b448a406bfb08e74a0ecc7e27af787afaf
parent3def66880874e5d0f06a48abfb6d3a95b6b0dae4 (diff)
WIP color fonts supportprivate/khaledhosny/color-fonts
Needs https://github.com/harfbuzz/harfbuzz/pull/1016 Change-Id: If3a23f8b07490b68de950b583485e7845a258b57
-rw-r--r--download.lst4
-rw-r--r--external/harfbuzz/UnpackedTarball_harfbuzz.mk5
-rw-r--r--vcl/inc/sallayout.hxx16
-rw-r--r--vcl/source/gdi/CommonSalLayout.cxx46
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx41
5 files changed, 102 insertions, 10 deletions
diff --git a/download.lst b/download.lst
index c05c99ba4dc0..748b19f0f9a7 100644
--- a/download.lst
+++ b/download.lst
@@ -94,8 +94,8 @@ export GPGME_SHA256SUM := 1b29fedb8bfad775e70eafac5b0590621683b2d9869db994568e64
export GPGME_TARBALL := gpgme-1.9.0.tar.bz2
export GRAPHITE_SHA256SUM := aa5e58356cd084000609ebbd93fef456a1bc0ab9e46fea20e81552fb286232a9
export GRAPHITE_TARBALL := graphite2-minimal-1.3.10.tgz
-export HARFBUZZ_SHA256SUM := b5d6ac8415f97f3540d73f3f91c41c5c10f8a4d76350f11a7184062aae88ac0b
-export HARFBUZZ_TARBALL := harfbuzz-1.7.4.tar.bz2
+export HARFBUZZ_SHA256SUM := 695c68b7022061395a52556c0e8cdb58ee6068b81f3dd6d3d11a5076c2585be2
+export HARFBUZZ_TARBALL := harfbuzz-1.7.6.tar.bz2
export HSQLDB_SHA256SUM := d30b13f4ba2e3b6a2d4f020c0dee0a9fb9fc6fbcc2d561f36b78da4bf3802370
export HSQLDB_TARBALL := 17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
export HUNSPELL_SHA256SUM := 3cd9ceb062fe5814f668e4f22b2fa6e3ba0b339b921739541ce180cac4d6f4c4
diff --git a/external/harfbuzz/UnpackedTarball_harfbuzz.mk b/external/harfbuzz/UnpackedTarball_harfbuzz.mk
index 74c990c0c1aa..fca6a394ddc3 100644
--- a/external/harfbuzz/UnpackedTarball_harfbuzz.mk
+++ b/external/harfbuzz/UnpackedTarball_harfbuzz.mk
@@ -15,11 +15,6 @@ $(eval $(call gb_UnpackedTarball_update_autoconf_configs,harfbuzz))
$(eval $(call gb_UnpackedTarball_set_patchlevel,harfbuzz,0))
-$(eval $(call gb_UnpackedTarball_add_patches,harfbuzz, \
- external/harfbuzz/clang-cl.patch \
- external/harfbuzz/ubsan.patch \
-))
-
ifneq ($(ENABLE_RUNTIME_OPTIMIZATIONS),TRUE)
$(eval $(call gb_UnpackedTarball_add_patches,harfbuzz, \
external/harfbuzz/harfbuzz-rtti.patch \
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index e07d51e8b3e8..c390836d4ea9 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -251,6 +251,17 @@ private:
typedef sal_uInt16 sal_GlyphId;
+
+namespace vcl {
+
+struct ColorGlyph
+{
+ sal_GlyphId mnGlyphId;
+ uint32_t mnColor;
+};
+
+}
+
struct GlyphItem
{
int mnFlags;
@@ -266,9 +277,11 @@ struct GlyphItem
int mnFallbackLevel;
+ std::vector<vcl::ColorGlyph> maColorLayers;
+
public:
GlyphItem(int nCharPos, int nCharCount, sal_GlyphId aGlyphId, const Point& rLinearPos,
- long nFlags, int nOrigWidth, int nXOffset )
+ long nFlags, int nOrigWidth, int nXOffset, std::vector<vcl::ColorGlyph> aColorLayers=std::vector<vcl::ColorGlyph>())
: mnFlags(nFlags)
, mnCharPos(nCharPos)
, mnCharCount(nCharCount)
@@ -278,6 +291,7 @@ public:
, maGlyphId(aGlyphId)
, maLinearPos(rLinearPos)
, mnFallbackLevel(0)
+ , maColorLayers(aColorLayers)
{ }
enum {
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index ddb3986b277d..3b1afae4e9be 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -553,6 +553,27 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
ParseFeatures(mrFontSelData.maTargetName);
+ std::vector<hb_ot_color_t> aColorPalette;
+ if (hb_ot_color_has_cpal_data(pHbFace) && hb_ot_color_has_colr_data(pHbFace))
+ {
+ uint32_t nColors = hb_ot_color_get_palette_colors (pHbFace, 0, 0, nullptr, nullptr);
+ if (nColors)
+ {
+ for (uint32_t i = 0; i < nColors; i++)
+ {
+ uint32_t nCount = 1;
+ hb_ot_color_t aColor;
+ hb_ot_color_get_palette_colors (pHbFace, 0, i, &nCount, &aColor);
+ if (!nCount)
+ {
+ aColorPalette.clear();
+ break;
+ }
+ aColorPalette.push_back(aColor);
+ }
+ }
+ }
+
double nXScale = 0;
double nYScale = 0;
getScale(&nXScale, &nYScale);
@@ -814,9 +835,32 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
nXOffset = std::lround(nXOffset * nXScale);
nYOffset = std::lround(nYOffset * nYScale);
+ std::vector<vcl::ColorGlyph> aColorLayers;
+ if (!aColorPalette.empty())
+ {
+ uint32_t nLayers = hb_ot_color_get_color_layers (pHbFace, nGlyphIndex, 0, nullptr, nullptr, nullptr);
+ if (nLayers)
+ {
+ for (uint32_t nLayer = 0; nLayer < nLayers; nLayer++)
+ {
+ hb_codepoint_t nLayerGlyphId;
+ uint32_t nLayerColorId;
+ uint32_t nCount = 1;
+ hb_ot_color_get_color_layers (pHbFace, nGlyphIndex, nLayer, &nCount, &nLayerGlyphId, &nLayerColorId);
+ if (nCount)
+ {
+ uint32_t nColor = 0xFF;
+ if (nLayerColorId != 0xFFFF)
+ nColor = aColorPalette[nLayerColorId];
+ aColorLayers.push_back({ static_cast<sal_GlyphId>(nLayerGlyphId), nColor });
+ }
+ }
+ }
+ }
+
Point aNewPos(aCurrPos.X() + nXOffset, aCurrPos.Y() + nYOffset);
const GlyphItem aGI(nCharPos, nCharCount, nGlyphIndex, aNewPos, nGlyphFlags,
- nAdvance, nXOffset);
+ nAdvance, nXOffset, aColorLayers);
AppendGlyph(aGI);
aCurrPos.AdjustX(nAdvance );
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 00532c8644b9..34e58a319104 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -157,8 +157,10 @@ void CairoTextRender::DrawTextLayout(const CommonSalLayout& rLayout)
std::vector<cairo_glyph_t> cairo_glyphs;
std::vector<int> glyph_extrarotation;
+ std::vector<std::vector<vcl::ColorGlyph>> color_layers;
cairo_glyphs.reserve( 256 );
+ bool bHasGlyphColor = false;
Point aPos;
const GlyphItem* pGlyph;
int nStart = 0;
@@ -174,6 +176,10 @@ void CairoTextRender::DrawTextLayout(const CommonSalLayout& rLayout)
glyph_extrarotation.push_back(1);
else
glyph_extrarotation.push_back(0);
+
+ if (!pGlyph->maColorLayers.empty())
+ bHasGlyphColor = true;
+ color_layers.push_back(pGlyph->maColorLayers);
}
if (cairo_glyphs.empty())
@@ -297,7 +303,40 @@ void CairoTextRender::DrawTextLayout(const CommonSalLayout& rLayout)
}
cairo_set_font_matrix(cr, &m);
- cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
+ if (SAL_LIKELY(!bHasGlyphColor))
+ cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
+ else
+ {
+ for (size_t i = 0; i < nLen; i++)
+ {
+ const auto& layers = color_layers[nStartIndex + i];
+ if (layers.empty())
+ {
+ cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex + i], 1);
+ }
+ else
+ {
+ for (const auto& layer : layers)
+ {
+ cairo_set_source_rgba(cr,
+ ((layer.mnColor >> 8) & 0xFF)/255.0,
+ ((layer.mnColor >> 16) & 0xFF)/255.0,
+ ((layer.mnColor >> 24) & 0xFF)/255.0,
+ (layer.mnColor & 0xFF)/255.0);
+
+ cairo_glyph_t g;
+ g.index = layer.mnGlyphId;
+ g.x = cairo_glyphs[nStartIndex + i].x;
+ g.y = cairo_glyphs[nStartIndex + i].y;
+ cairo_show_glyphs(cr, &g, 1);
+ }
+ cairo_set_source_rgb(cr,
+ mnTextColor.GetRed()/255.0,
+ mnTextColor.GetGreen()/255.0,
+ mnTextColor.GetBlue()/255.0);
+ }
+ }
+ }
#if OSL_DEBUG_LEVEL > 2
//draw origin