summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RepositoryExternal.mk1
-rw-r--r--external/skia/UnpackedTarball_skia.mk1
-rw-r--r--external/skia/fontconfig-get-typeface.patch.032
-rw-r--r--vcl/Library_vcl.mk3
-rw-r--r--vcl/Library_vclplug_gen.mk9
-rw-r--r--vcl/inc/skia/gdiimpl.hxx3
-rw-r--r--vcl/inc/skia/x11/textrender.hxx40
-rw-r--r--vcl/inc/unx/fc_fontoptions.hxx2
-rw-r--r--vcl/inc/unx/glyphcache.hxx4
-rw-r--r--vcl/skia/gdiimpl.cxx44
-rw-r--r--vcl/skia/x11/textrender.cxx79
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx14
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx5
-rw-r--r--vcl/unx/generic/glyphs/freetype_glyphcache.cxx18
14 files changed, 234 insertions, 21 deletions
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index a0de7e340de8..7079e9bcf61b 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -127,6 +127,7 @@ $(call gb_LinkTarget_set_include,$(1),\
-I$(call gb_UnpackedTarball_get_dir,skia)/include/effects \
-I$(call gb_UnpackedTarball_get_dir,skia)/include/gpu \
-I$(call gb_UnpackedTarball_get_dir,skia)/include/config \
+ -I$(call gb_UnpackedTarball_get_dir,skia)/include/ports \
-I$(call gb_UnpackedTarball_get_dir,skia)/include/third_party/vulkan \
-I$(call gb_UnpackedTarball_get_dir,skia)/tools/gpu \
-I$(call gb_UnpackedTarball_get_dir,skia) \
diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk
index 33fcf05b6a81..6ffde2006590 100644
--- a/external/skia/UnpackedTarball_skia.mk
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -27,6 +27,7 @@ skia_patches := \
fix-gcc-x86.patch.1 \
msvc-vectorcall-sse.patch.1 \
clang11-flax-vector-conversion.patch.0 \
+ fontconfig-get-typeface.patch.0 \
$(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
diff --git a/external/skia/fontconfig-get-typeface.patch.0 b/external/skia/fontconfig-get-typeface.patch.0
new file mode 100644
index 000000000000..a7a82bfa07f4
--- /dev/null
+++ b/external/skia/fontconfig-get-typeface.patch.0
@@ -0,0 +1,32 @@
+--- ./src/ports/SkFontMgr_fontconfig.cpp.sav 2020-01-20 16:42:51.322186451 +0100
++++ ./src/ports/SkFontMgr_fontconfig.cpp 2020-03-13 11:25:15.793936659 +0100
+@@ -699,6 +699,7 @@ class SkFontMgr_fontconfig : public SkFo
+ /** Creates a typeface using a typeface cache.
+ * @param pattern a complete pattern from FcFontRenderPrepare.
+ */
++public:
+ sk_sp<SkTypeface> createTypefaceFromFcPattern(FcPattern* pattern) const {
+ FCLocker::AssertHeld();
+ SkAutoMutexExclusive ama(fTFCacheMutex);
+@@ -1039,3 +1040,9 @@ protected:
+ SK_API sk_sp<SkFontMgr> SkFontMgr_New_FontConfig(FcConfig* fc) {
+ return sk_make_sp<SkFontMgr_fontconfig>(fc);
+ }
++
++SK_API sk_sp<SkTypeface> SkFontMgr_createTypefaceFromFcPattern(const sk_sp<SkFontMgr>& mgr, FcPattern* pattern)
++{
++ FCLocker lock;
++ return static_cast<SkFontMgr_fontconfig*>(mgr.get())->createTypefaceFromFcPattern(pattern);
++}
+--- ./include/ports/SkFontMgr_fontconfig.h.sav 2019-09-19 11:38:00.943185323 +0200
++++ ./include/ports/SkFontMgr_fontconfig.h 2020-03-13 11:31:48.025716543 +0100
+@@ -19,4 +19,9 @@ class SkFontMgr;
+ */
+ SK_API sk_sp<SkFontMgr> SkFontMgr_New_FontConfig(FcConfig* fc);
+
++struct _FcPattern;
++typedef struct _FcPattern FcPattern;
++class SkTypeface;
++SK_API sk_sp<SkTypeface> SkFontMgr_createTypefaceFromFcPattern(const sk_sp<SkFontMgr>& mgr, FcPattern* pattern);
++
+ #endif // #ifndef SkFontMgr_fontconfig_DEFINED
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 9becb8efc977..39d99957883e 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -599,7 +599,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/skia/packedsurfaceatlas \
vcl/skia/salbmp \
vcl/skia/zone \
- vcl/skia/gdiimpl) \
+ vcl/skia/gdiimpl \
+ ) \
))
# runtime dependency
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 500783ed67e1..34ca4df4ba50 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -60,7 +60,10 @@ $(eval $(call gb_Library_use_externals,vclplug_gen,\
icuuc \
valgrind \
Xrender \
- $(if $(filter SKIA,$(BUILD_TYPE)),skia) \
+ $(if $(filter SKIA,$(BUILD_TYPE)), \
+ skia \
+ fontconfig \
+ ) \
))
$(eval $(call gb_Library_add_libs,vclplug_gen,\
@@ -111,7 +114,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
$(if $(filter SKIA,$(BUILD_TYPE)), \
vcl/skia/x11/cairotextrender \
vcl/skia/x11/gdiimpl \
- vcl/skia/x11/salvd) \
+ vcl/skia/x11/salvd \
+ vcl/skia/x11/textrender \
+ ) \
))
# ultimately we want to split the x11 dependencies out
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 46b3f7bcd334..a7de1cfc4872 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -32,6 +32,7 @@
#include <postwin.h>
class SkiaFlushIdle;
+class GenericSalLayout;
class VCL_DLLPUBLIC SkiaSalGraphicsImpl : public SalGraphicsImpl
{
@@ -202,6 +203,8 @@ public:
void drawBitmap(const SalTwoRect& rPosAry, const SkBitmap& aBitmap,
SkBlendMode eBlendMode = SkBlendMode::kSrcOver);
+ void drawGenericLayout(const GenericSalLayout& layout, Color textColor, const SkFont& font);
+
protected:
// To be called before any drawing.
void preDraw();
diff --git a/vcl/inc/skia/x11/textrender.hxx b/vcl/inc/skia/x11/textrender.hxx
new file mode 100644
index 000000000000..2aeda63cfb5c
--- /dev/null
+++ b/vcl/inc/skia/x11/textrender.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_SKIA_TEXTRENDER_HXX
+#define INCLUDED_VCL_INC_SKIA_TEXTRENDER_HXX
+
+#include <unx/freetypetextrender.hxx>
+
+#include <SkFontMgr.h>
+#include <SkFontMgr_fontconfig.h>
+
+class VCL_DLLPUBLIC SkiaTextRender : public FreeTypeTextRenderImpl
+{
+public:
+ virtual void DrawTextLayout(const GenericSalLayout&, const SalGraphics&) override;
+ virtual void ClearDevFontCache() override;
+
+private:
+ sk_sp<SkFontMgr> fontManager;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/fc_fontoptions.hxx b/vcl/inc/unx/fc_fontoptions.hxx
index fe1bbef20452..de6ed2aba5df 100644
--- a/vcl/inc/unx/fc_fontoptions.hxx
+++ b/vcl/inc/unx/fc_fontoptions.hxx
@@ -23,7 +23,7 @@
#include <rtl/string.hxx>
typedef struct _FcPattern FcPattern;
-class FontConfigFontOptions
+class VCL_DLLPUBLIC FontConfigFontOptions
{
public:
FontConfigFontOptions(FcPattern* pPattern) :
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index d2352a4ffd44..38c51a036a1b 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -136,7 +136,7 @@ private:
FontFileList m_aFontFileList;
};
-class FreetypeFont final
+class VCL_DLLPUBLIC FreetypeFont final
{
public:
~FreetypeFont();
@@ -169,7 +169,7 @@ public:
// in starmath at a fairly low stretch ratio. This appears fixed in 2.9 with
// https://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=91015cb41d8f56777f93394f5a60914bc0c0f330
// "Improve complex rendering at high ppem"
- static bool AlmostHorizontalDrainsRenderingPool();
+ static bool AlmostHorizontalDrainsRenderingPool(int nRatio, const FontSelectPattern& rFSD);
private:
friend class FreetypeManager;
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 7dfd667e8a63..3bf0724de354 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -33,6 +33,8 @@
#include <SkRegion.h>
#include <SkDashPathEffect.h>
#include <GrBackendSurface.h>
+#include <SkTextBlob.h>
+#include <SkRSXform.h>
#include <numeric>
#include <basegfx/polygon/b2dpolygontools.hxx>
@@ -1258,6 +1260,48 @@ bool SkiaSalGraphicsImpl::drawGradient(const tools::PolyPolygon&, const Gradient
return false;
}
+static double toRadian(int degree10th) { return (3600 - degree10th) * M_PI / 1800.0; }
+static double toCos(int degree10th) { return SkScalarCos(toRadian(degree10th)); }
+static double toSin(int degree10th) { return SkScalarSin(toRadian(degree10th)); }
+
+void SkiaSalGraphicsImpl::drawGenericLayout(const GenericSalLayout& layout, Color textColor,
+ const SkFont& font)
+{
+ std::vector<SkGlyphID> glyphIds;
+ std::vector<SkRSXform> glyphForms;
+ glyphIds.reserve(256);
+ glyphForms.reserve(256);
+ Point aPos;
+ const GlyphItem* pGlyph;
+ int nStart = 0;
+ double orientationAngle = layout.GetOrientation(); // 10th of degree
+ while (layout.GetNextGlyph(&pGlyph, aPos, nStart))
+ {
+ glyphIds.push_back(pGlyph->glyphId());
+ double angle = orientationAngle;
+ if (pGlyph->IsVertical())
+ angle += 900; // 90 degree
+ SkRSXform form = SkRSXform::Make(toCos(angle), toSin(angle), aPos.X(), aPos.Y());
+ glyphForms.emplace_back(std::move(form));
+ }
+ if (glyphIds.empty())
+ return;
+ sk_sp<SkTextBlob> textBlob
+ = SkTextBlob::MakeFromRSXform(glyphIds.data(), glyphIds.size() * sizeof(SkGlyphID),
+ glyphForms.data(), font, SkTextEncoding::kGlyphID);
+ preDraw();
+ SAL_INFO("vcl.skia", "drawtextblob("
+ << this << "): "
+ << tools::Rectangle(textBlob->bounds().x(), textBlob->bounds().y(),
+ textBlob->bounds().width(),
+ textBlob->bounds().height())
+ << ":" << textColor);
+ SkPaint paint;
+ paint.setColor(toSkColor(textColor));
+ getDrawCanvas()->drawTextBlob(textBlob, 0, 0, paint);
+ postDraw();
+}
+
bool SkiaSalGraphicsImpl::supportsOperation(OutDevSupportType eType) const
{
switch (eType)
diff --git a/vcl/skia/x11/textrender.cxx b/vcl/skia/x11/textrender.cxx
new file mode 100644
index 000000000000..02911fcf5154
--- /dev/null
+++ b/vcl/skia/x11/textrender.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <skia/x11/textrender.hxx>
+
+#include <unx/fc_fontoptions.hxx>
+#include <unx/freetype_glyphcache.hxx>
+#include <vcl/svapp.hxx>
+#include <sallayout.hxx>
+#include <skia/gdiimpl.hxx>
+
+#include <SkFont.h>
+#include <SkFontMgr_fontconfig.h>
+
+void SkiaTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalGraphics& rGraphics)
+{
+ const FreetypeFontInstance& rInstance = static_cast<FreetypeFontInstance&>(rLayout.GetFont());
+ const FreetypeFont& rFont = *rInstance.GetFreetypeFont();
+ const FontSelectPattern& rFSD = rInstance.GetFontSelectPattern();
+ int nHeight = rFSD.mnHeight;
+ int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
+ if (nWidth == 0 || nHeight == 0)
+ return;
+
+ if (FreetypeFont::AlmostHorizontalDrainsRenderingPool(nWidth * 10 / nHeight, rFSD))
+ return;
+
+ if (!fontManager)
+ {
+ // Get the global FcConfig that our VCL fontconfig code uses, and refcount it.
+ fontManager = SkFontMgr_New_FontConfig(FcConfigReference(nullptr));
+ }
+ sk_sp<SkTypeface> typeface
+ = SkFontMgr_createTypefaceFromFcPattern(fontManager, rFont.GetFontOptions()->GetPattern());
+ SkFont font(typeface, nHeight);
+ // TODO are these correct?
+ if (rFont.NeedsArtificialItalic())
+ font.setSkewX(-0x6000L / 0x10000L);
+ if (rFont.NeedsArtificialBold())
+ font.setEmbolden(true);
+ font.setEdging(rFont.GetAntialiasAdvice() ? SkFont::Edging::kAntiAlias
+ : SkFont::Edging::kAlias);
+
+ assert(dynamic_cast<SkiaSalGraphicsImpl*>(rGraphics.GetImpl()));
+ SkiaSalGraphicsImpl* impl = static_cast<SkiaSalGraphicsImpl*>(rGraphics.GetImpl());
+ impl->drawGenericLayout(rLayout, mnTextColor, font);
+}
+
+void SkiaTextRender::ClearDevFontCache() { fontManager.reset(); }
+
+#if 0
+// SKIA TODO
+void FontConfigFontOptions::cairo_font_options_substitute(FcPattern* pPattern)
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ const cairo_font_options_t* pFontOptions = pSVData->mpDefInst->GetCairoFontOptions();
+ if( !pFontOptions )
+ return;
+ cairo_ft_font_options_substitute(pFontOptions, pPattern);
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 36ed2cb6bed2..8276029db557 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -148,20 +148,8 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG
return;
int nRatio = nWidth * 10 / nHeight;
- if (nRatio > 100 && rFSD.maTargetName == "OpenSymbol" && FreetypeFont::AlmostHorizontalDrainsRenderingPool())
- {
- // tdf#127189 FreeType <= 2.8 will fail to render stretched horizontal
- // brace glyphs in starmath at a fairly low stretch ratio. The failure
- // will set CAIRO_STATUS_FREETYPE_ERROR on the surface which cannot be
- // cleared, so all further painting to the surface fails.
-
- // This appears fixed in >= freetype 2.9
-
- // Restrict this bodge to a stretch ratio > ~10 of the OpenSymbol font
- // where it has been seen in practice.
- SAL_WARN("vcl", "rendering text would fail with stretch ratio of: " << nRatio << ", with FreeType <= 2.8");
+ if (FreetypeFont::AlmostHorizontalDrainsRenderingPool(nRatio, rFSD))
return;
- }
/*
* It might be ideal to cache surface and cairo context between calls and
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index d5b6281bed3b..16a7c40046b9 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -59,6 +59,7 @@
#if HAVE_FEATURE_SKIA
#include <skia/x11/gdiimpl.hxx>
#include <skia/x11/cairotextrender.hxx>
+#include <skia/x11/textrender.hxx>
#endif
X11SalGraphics::X11SalGraphics():
@@ -86,7 +87,11 @@ X11SalGraphics::X11SalGraphics():
if (m_bSkia)
{
mxImpl.reset(new X11SkiaSalGraphicsImpl(*this));
+#if 1
+ mxTextRenderImpl.reset(new SkiaTextRender);
+#else // old method, probably can be removed once native Skia render works well
mxTextRenderImpl.reset(new SkiaX11CairoTextRender(*this));
+#endif
}
else
#endif
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 7408b5f780d4..08a8521b5627 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -308,10 +308,24 @@ namespace
}
}
-bool FreetypeFont::AlmostHorizontalDrainsRenderingPool()
+bool FreetypeFont::AlmostHorizontalDrainsRenderingPool(int nRatio, const FontSelectPattern& rFSD)
{
static bool bAlmostHorizontalDrainsRenderingPool = DoesAlmostHorizontalDrainRenderingPool();
- return bAlmostHorizontalDrainsRenderingPool;
+ if (nRatio > 100 && rFSD.maTargetName == "OpenSymbol" && bAlmostHorizontalDrainsRenderingPool)
+ {
+ // tdf#127189 FreeType <= 2.8 will fail to render stretched horizontal
+ // brace glyphs in starmath at a fairly low stretch ratio. The failure
+ // will set CAIRO_STATUS_FREETYPE_ERROR on the surface which cannot be
+ // cleared, so all further painting to the surface fails.
+
+ // This appears fixed in >= freetype 2.9
+
+ // Restrict this bodge to a stretch ratio > ~10 of the OpenSymbol font
+ // where it has been seen in practice.
+ SAL_WARN("vcl", "rendering text would fail with stretch ratio of: " << nRatio << ", with FreeType <= 2.8");
+ return true;
+ }
+ return false;
}
FT_Face FreetypeFont::GetFtFace() const