diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2018-05-01 23:03:46 +0200 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2018-05-01 23:03:46 +0200 |
commit | fa1ec9461e2f78655e9aa17473dba085b0b6015d (patch) | |
tree | 40d683b448a406bfb08e74a0ecc7e27af787afaf | |
parent | 3def66880874e5d0f06a48abfb6d3a95b6b0dae4 (diff) |
WIP color fonts supportprivate/khaledhosny/color-fonts
Needs https://github.com/harfbuzz/harfbuzz/pull/1016
Change-Id: If3a23f8b07490b68de950b583485e7845a258b57
-rw-r--r-- | download.lst | 4 | ||||
-rw-r--r-- | external/harfbuzz/UnpackedTarball_harfbuzz.mk | 5 | ||||
-rw-r--r-- | vcl/inc/sallayout.hxx | 16 | ||||
-rw-r--r-- | vcl/source/gdi/CommonSalLayout.cxx | 46 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/cairotextrender.cxx | 41 |
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 |