diff --git a/vcl/CppunitTest_vcl_skia.mk b/vcl/CppunitTest_vcl_skia.mk index 094bba75fafa..668791d58834 100644 --- a/vcl/CppunitTest_vcl_skia.mk +++ b/vcl/CppunitTest_vcl_skia.mk @@ -37,6 +37,7 @@ $(eval $(call gb_CppunitTest_use_libraries,vcl_skia, \ $(eval $(call gb_CppunitTest_use_externals,vcl_skia, \ boost_headers \ $(if $(filter SKIA,$(BUILD_TYPE)),skia) \ + harfbuzz \ )) $(eval $(call gb_CppunitTest_use_sdk_api,vcl_skia)) diff --git a/vcl/inc/skia/utils.hxx b/vcl/inc/skia/utils.hxx index e78abdd5ab70..e699f8b86790 100644 --- a/vcl/inc/skia/utils.hxx +++ b/vcl/inc/skia/utils.hxx @@ -27,12 +27,14 @@ #include #include #include +#include #include #include #include #include +#include #if defined __GNUC__ && !defined __clang__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" @@ -138,6 +140,9 @@ VCL_DLLPUBLIC const SkSurfaceProps* surfaceProps(); // Set pixel geometry to be used by SkSurfaceProps. VCL_DLLPUBLIC void setPixelGeometry(SkPixelGeometry pixelGeometry); +VCL_DLLPUBLIC sk_sp applyVariations(const sk_sp& skTypeface, + const LogicalFontInstance& font); + inline bool isUnitTestRunning(const char* name = nullptr) { if (name == nullptr) diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx index cc84c26e1d21..3884319c53d6 100644 --- a/vcl/skia/SkiaHelper.cxx +++ b/vcl/skia/SkiaHelper.cxx @@ -57,6 +57,8 @@ bool isAlphaMaskBlendingEnabled() { return false; } #include #include #include +#include +#include #include #include #if defined(MACOSX) @@ -909,6 +911,29 @@ void dump(const sk_sp& image, const char* file) ostream.write(static_cast(data->data()), data->size()); } +sk_sp applyVariations(const sk_sp& skTypeface, + const LogicalFontInstance& font) +{ + const auto& variations = font.GetVariations(); + if (variations.empty() || !skTypeface) + return skTypeface; + + std::vector skCoords; + skCoords.reserve(variations.size()); + for (const auto& var : variations) + skCoords.push_back({ var.tag, var.value }); + + SkFontArguments fontArgs; + SkFontArguments::VariationPosition varPosition + = { skCoords.data(), static_cast(skCoords.size()) }; + fontArgs.setVariationDesignPosition(varPosition); + + sk_sp variationFace = skTypeface->makeClone(fontArgs); + if (variationFace) + return variationFace; + return skTypeface; +} + #ifdef DBG_UTIL void prefillSurface(const sk_sp& surface) { diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx index 5dd219ba429e..c5c5a9aa7e2f 100644 --- a/vcl/skia/osx/gdiimpl.cxx +++ b/vcl/skia/osx/gdiimpl.cxx @@ -381,7 +381,8 @@ void AquaSkiaSalGraphicsImpl::drawTextLayout(const GenericSalLayout& rLayout) } } - sk_sp typeface = SkMakeTypefaceFromCTFont(rFont.GetCTFont()); + sk_sp typeface + = SkiaHelper::applyVariations(SkMakeTypefaceFromCTFont(rFont.GetCTFont()), rFont); SkFont font(typeface); font.setSize(nHeight); // font.setScaleX(rFont.mfFontStretch); TODO diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index f085f915ef7e..7ab8d2bbff45 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -268,6 +268,7 @@ bool WinSkiaSalGraphicsImpl::DrawTextLayout(const GenericSalLayout& rLayout) if (!typeface) return false; } + typeface = SkiaHelper::applyVariations(typeface, rWinFont); // Cache the typeface. rWinFont.SetSkiaTypeface(typeface, dwrite); } diff --git a/vcl/skia/x11/textrender.cxx b/vcl/skia/x11/textrender.cxx index 4899dff28379..07ce167c045a 100644 --- a/vcl/skia/x11/textrender.cxx +++ b/vcl/skia/x11/textrender.cxx @@ -64,8 +64,9 @@ void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGr fontManager = SkFontMgr_New_FontConfig(FcConfigReference(nullptr), SkFontScanner_Make_FreeType()); } - sk_sp typeface - = SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()); + sk_sp typeface = SkiaHelper::applyVariations( + SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern()), + rInstance); SkFont font(typeface); font.setSize(nHeight); font.setScaleX(nWidth / nHeight);