desktop/source/lib/init.cxx                              |   20 +++
 external/cairo/ExternalPackage_cairo.mk                  |    3 
 external/cairo/UnpackedTarball_cairo.mk                  |    2 
 external/cairo/cairo/cairo-fd-hack.patch.0               |   15 ++
 external/cairo/cairo/libcairo-bundled-soname.patch.0     |   12 ++
 external/fontconfig/ExternalPackage_fontconfig.mk        |   16 ++
 external/fontconfig/ExternalProject_fontconfig.mk        |   15 ++
 external/fontconfig/Module_fontconfig.mk                 |    1 
 external/fontconfig/UnpackedTarball_fontconfig.mk        |    1 
 external/fontconfig/libfontconfig-bundled-soname.patch.0 |   11 +
 external/freetype/ExternalPackage_freetype.mk            |   16 ++
 external/freetype/ExternalProject_freetype.mk            |    5 
 external/freetype/Module_freetype.mk                     |    1 
 external/freetype/UnpackedTarball_freetype.mk            |    2 
 external/freetype/freetype-fd-hack.patch.0               |   53 ++++++++
 external/freetype/libfreetype-bundled-soname.patch.0     |   11 +
 external/harfbuzz/ExternalPackage_harfbuzz.mk            |   17 ++
 external/harfbuzz/ExternalProject_harfbuzz.mk            |    9 +
 external/harfbuzz/Module_harfbuzz.mk                     |    1 
 external/harfbuzz/UnpackedTarball_harfbuzz.mk            |    4 
 external/harfbuzz/harfbuzz-fd-hack.patch.0               |   24 ++++
 external/harfbuzz/libharfbuzz-bundled-soname.patch.0     |   24 ++++
 vcl/source/fontsubset/sft.cxx                            |   23 +++
 vcl/unx/generic/fontmanager/fontmanager.cxx              |   90 ++++++++-------
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx           |   13 ++
 25 files changed, 342 insertions(+), 47 deletions(-)

New commits:
commit d8b04077bb63f05efa256f353bfd6acb409a6983
Author:     Tor Lillqvist <t...@collabora.com>
AuthorDate: Tue Sep 20 16:07:14 2022 +0300
Commit:     Tor Lillqvist <t...@collabora.com>
CommitDate: Mon Sep 26 20:59:18 2022 +0200

    Enable opening of downloaded fonts only in ForKit in Online
    
    We want that only the ForKit process needs to have access to new font
    files added to a Collabora Online instance dynamically by downloading
    from a server. There are however many locations in the Kit process, in
    core and in external libraries like harfbuzz, where the code wants to
    open a font file.
    
    Handle this so that the ForKit process opens such a downloaded font
    file and doesn't close it. The file descriptor is thus inherited by
    Kit processes.  The font file pathname passed on to other code is a
    fake on in the format "/:FD:/%d" where the %d is the file descriptor
    of the opened font file. Add checks in all places where font files are
    opened, look for this special pathname format, and modify the code to
    just dup() the already open file descriptor in that case.
    
    All this is relevant for Linux only, as Collabora Online runs on
    Linux.
    
    Do the above for harfbuzz, cairo, fontconfig, and freetype.
    
    In addition make sure that these libraries when bundled, on Linux, are
    built as shared libraries, and won't be confused with the
    corresponding system libraries by making sure their sonames are
    different.
    
    Change-Id: I85ff853ac1d1f6b098a3c254a38e3fe3bca774c1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140243
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Michael Meeks <michael.me...@collabora.com>
    Tested-by: Michael Meeks <michael.me...@collabora.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 4eed88331948..a08c6d8b275d 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -24,6 +24,10 @@
 #include <postmac.h>
 #endif
 
+#ifdef LINUX
+#include <fcntl.h>
+#endif
+
 #ifdef ANDROID
 #include <osl/detail/android-bootstrap.h>
 #endif
@@ -4330,13 +4334,27 @@ static void lo_setOption(LibreOfficeKit* /*pThis*/, 
const char *pOption, const c
         else
             sal_detail_set_log_selector(pCurrentSalLogOverride);
     }
+#ifdef LINUX
     else if (strcmp(pOption, "addfont") == 0)
     {
+        if (memcmp(pValue, "file://", 7) == 0)
+            pValue += 7;
+
+        int fd = open(pValue, O_RDONLY);
+        if (fd == -1)
+        {
+            std::cerr << "Could not open font file '" << pValue << "': " << 
strerror(errno) << std::endl;
+            return;
+        }
+
+        OUString sMagicFileName = "file:///:FD:/" + OUString::number(fd);
+
         OutputDevice *pDevice = Application::GetDefaultDevice();
         OutputDevice::ImplClearAllFontData(false);
-        pDevice->AddTempDevFont(OUString::fromUtf8(pValue), "");
+        pDevice->AddTempDevFont(sMagicFileName, "");
         OutputDevice::ImplRefreshAllFontData(false);
     }
+#endif
 }
 
 static void lo_dumpState (LibreOfficeKit* pThis, const char* /* pOptions */, 
char** pState)
diff --git a/external/cairo/ExternalPackage_cairo.mk 
b/external/cairo/ExternalPackage_cairo.mk
index 116db8a3499d..74a46688406a 100644
--- a/external/cairo/ExternalPackage_cairo.mk
+++ b/external/cairo/ExternalPackage_cairo.mk
@@ -12,7 +12,8 @@ $(eval $(call gb_ExternalPackage_ExternalPackage,cairo,cairo))
 $(eval $(call gb_ExternalPackage_use_external_project,cairo,cairo))
 
 ifneq ($(DISABLE_DYNLOADING),TRUE)
-$(eval $(call 
gb_ExternalPackage_add_file,cairo,$(LIBO_LIB_FOLDER)/libcairo.so.2,src/.libs/libcairo.so.2.1170$(CAIRO_VERSION_MICRO).0))
+$(eval $(call 
gb_ExternalPackage_add_file,cairo,$(LIBO_LIB_FOLDER)/libcairo-lo.so.2.1170$(CAIRO_VERSION_MICRO).0,src/.libs/libcairo-lo.so.2.1170$(CAIRO_VERSION_MICRO).0))
+$(eval $(call 
gb_ExternalPackage_add_file,cairo,$(LIBO_LIB_FOLDER)/libcairo-lo.so.2,src/.libs/libcairo-lo.so.2))
 endif
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/cairo/UnpackedTarball_cairo.mk 
b/external/cairo/UnpackedTarball_cairo.mk
index 5e83b526e52e..8599647a8f9c 100644
--- a/external/cairo/UnpackedTarball_cairo.mk
+++ b/external/cairo/UnpackedTarball_cairo.mk
@@ -18,6 +18,8 @@ $(eval $(call gb_UnpackedTarball_add_patches,cairo,\
        external/cairo/cairo/cairo.oldfreetype.patch \
        external/cairo/cairo/san.patch.0 \
        external/cairo/cairo/0001-Fix-mask-usage-in-image-compositor.patch.1 \
+       external/cairo/cairo/libcairo-bundled-soname.patch.0 \
+       external/cairo/cairo/cairo-fd-hack.patch.0 \
 ))
 
 ifeq ($(OS),iOS)
diff --git a/external/cairo/cairo/cairo-fd-hack.patch.0 
b/external/cairo/cairo/cairo-fd-hack.patch.0
new file mode 100644
index 000000000000..e5d980e94dfb
--- /dev/null
+++ b/external/cairo/cairo/cairo-fd-hack.patch.0
@@ -0,0 +1,15 @@
+# -*- Mode: Diff -*-
+--- src/cairo-ft-font.c
++++ src/cairo-ft-font.c
+@@ -737,7 +737,10 @@
+     if (ret == FcResultOutOfMemory)
+       return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+     if (ret == FcResultMatch) {
+-      if (access (filename, R_OK) == 0) {
++       int nFD = -1;
++       int n;
++       if ((sscanf (filename, "/:FD:/%d%n", &nFD, &n) == 1 && filename[n] == 
'\0') ||
++          access (filename, R_OK) == 0) {
+           /* If FC_INDEX is not set, we just use 0 */
+           ret = FcPatternGetInteger (pattern, FC_INDEX, 0, &id);
+           if (ret == FcResultOutOfMemory)
diff --git a/external/cairo/cairo/libcairo-bundled-soname.patch.0 
b/external/cairo/cairo/libcairo-bundled-soname.patch.0
new file mode 100644
index 000000000000..9576926b178f
--- /dev/null
+++ b/external/cairo/cairo/libcairo-bundled-soname.patch.0
@@ -0,0 +1,12 @@
+# -*- Mode: Diff -*-
+--- src/Makefile.in
++++ src/Makefile.in
+@@ -2075,7 +2075,7 @@
+       $(enabled_cairo_sources) \
+       $(NULL)
+ 
+-libcairo_la_LDFLAGS = $(AM_LDFLAGS) -version-info 
$(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols)
++libcairo_la_LDFLAGS = $(AM_LDFLAGS) -version-info 
$(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols) -release lo 
-Wl,-soname -Wl,libcairo-lo.so.2
+ libcairo_la_LIBADD = $(CAIRO_LIBS) \
+       $(cairo_cxx_lib)
+ 
diff --git a/external/fontconfig/ExternalPackage_fontconfig.mk 
b/external/fontconfig/ExternalPackage_fontconfig.mk
new file mode 100644
index 000000000000..7114f80d9507
--- /dev/null
+++ b/external/fontconfig/ExternalPackage_fontconfig.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,fontconfig,fontconfig))
+
+$(eval $(call gb_ExternalPackage_use_external_project,fontconfig,fontconfig))
+
+$(eval $(call 
gb_ExternalPackage_add_file,fontconfig,$(LIBO_LIB_FOLDER)/libfontconfig-lo.so.1.12.0,src/.libs/libfontconfig-lo.so.1.12.0))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/ExternalProject_fontconfig.mk 
b/external/fontconfig/ExternalProject_fontconfig.mk
index 8cb9498fe763..ed283852f7bf 100644
--- a/external/fontconfig/ExternalProject_fontconfig.mk
+++ b/external/fontconfig/ExternalProject_fontconfig.mk
@@ -18,19 +18,30 @@ $(eval $(call 
gb_ExternalProject_register_targets,fontconfig,\
        build \
 ))
 
+# Can't have this inside the $(call gb_ExternalProject_run as it contains 
commas
+fontconfig_add_fonts=/usr/share/X11/fonts/Type1,/usr/share/X11/fonts/TTF,/usr/local/share/fonts
+
 $(call gb_ExternalProject_get_state_target,fontconfig,build) :
        $(call gb_Trace_StartRange,fontconfig,EXTERNAL)
        $(call gb_ExternalProject_run,build,\
                CFLAGS="$(CFLAGS) $(if $(debug),-g) $(gb_VISIBILITY_FLAGS) $(if 
$(filter EMSCRIPTEN,$(OS)),-pthread)" $(if $(filter ANDROID,$(OS)),LIBS="-lm") \
                $(gb_RUN_CONFIGURE) ./configure \
-                       --disable-shared \
                        --disable-silent-rules \
                        --with-pic \
                        $(if $(filter ANDROID,$(OS)),--with-arch=arm) \
                        --with-expat-includes=$(call 
gb_UnpackedTarball_get_dir,expat)/lib \
                        --with-expat-lib=$(gb_StaticLibrary_WORKDIR) \
                        --build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM) \
-                       $(if $(filter EMSCRIPTEN,$(OS)),ac_cv_func_fstatfs=no 
ac_cv_func_fstatvfs=no) \
+                       $(if $(filter ANDROID EMSCRIPTEN,$(OS)), \
+                               --disable-shared \
+                               ac_cv_func_fstatfs=no ac_cv_func_fstatvfs=no \
+                       ) \
+                       $(if $(filter LINUX,$(OS)), \
+                               --disable-static \
+                       ) \
+                       --prefix=/ \
+                       --with-add-fonts=$(fontconfig_add_fonts) \
+                       --with-cache-dir=/usr/lib/fontconfig/cache \
                && $(MAKE) -C src \
        )
        $(call gb_Trace_EndRange,fontconfig,EXTERNAL)
diff --git a/external/fontconfig/Module_fontconfig.mk 
b/external/fontconfig/Module_fontconfig.mk
index e755f8610db1..c97ad7a5d2d5 100644
--- a/external/fontconfig/Module_fontconfig.mk
+++ b/external/fontconfig/Module_fontconfig.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_Module_Module,fontconfig))
 $(eval $(call gb_Module_add_targets,fontconfig,\
        ExternalProject_fontconfig \
        UnpackedTarball_fontconfig \
+       $(if $(filter LINUX,$(OS)),ExternalPackage_fontconfig) \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/UnpackedTarball_fontconfig.mk 
b/external/fontconfig/UnpackedTarball_fontconfig.mk
index 6026a817c5ed..2e6fdfe4fd5c 100644
--- a/external/fontconfig/UnpackedTarball_fontconfig.mk
+++ b/external/fontconfig/UnpackedTarball_fontconfig.mk
@@ -13,6 +13,7 @@ $(eval $(call 
gb_UnpackedTarball_set_tarball,fontconfig,$(FONTCONFIG_TARBALL),,f
 
 $(eval $(call gb_UnpackedTarball_add_patches,fontconfig,\
        external/fontconfig/fontconfig-2.12.1.patch.1 \
+       external/fontconfig/libfontconfig-bundled-soname.patch.0 \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/fontconfig/libfontconfig-bundled-soname.patch.0 
b/external/fontconfig/libfontconfig-bundled-soname.patch.0
new file mode 100644
index 000000000000..390338e957e8
--- /dev/null
+++ b/external/fontconfig/libfontconfig-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+# -*- Mode: Diff -*-
+--- src/Makefile.in
++++ src/Makefile.in
+@@ -525,6 +525,6 @@
+ lib_LTLIBRARIES = libfontconfig.la
+ libfontconfig_la_LDFLAGS = \
+-      -version-info @LIBT_VERSION_INFO@ -no-undefined $(export_symbols)
++      -version-info @LIBT_VERSION_INFO@ -no-undefined $(export_symbols) 
-release lo -Wl,-soname -Wl,libfontconfig-lo.so.1.12.0
+ 
+ libfontconfig_la_LIBADD = $(ICONV_LIBS) $(FREETYPE_LIBS) $(LIBXML2_LIBS) 
$(EXPAT_LIBS) $(LTLIBINTL)
+ libfontconfig_la_DEPENDENCIES = $(fontconfig_def_dependency)
diff --git a/external/freetype/ExternalPackage_freetype.mk 
b/external/freetype/ExternalPackage_freetype.mk
new file mode 100644
index 000000000000..4709c60415c0
--- /dev/null
+++ b/external/freetype/ExternalPackage_freetype.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,freetype,freetype))
+
+$(eval $(call gb_ExternalPackage_use_external_project,freetype,freetype))
+
+$(eval $(call 
gb_ExternalPackage_add_file,freetype,$(LIBO_LIB_FOLDER)/libfreetype-lo.so.6.18.0,instdir/lib/libfreetype-lo.so.6.18.0))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/freetype/ExternalProject_freetype.mk 
b/external/freetype/ExternalProject_freetype.mk
index 4cb2920ae923..8cf533d8dfb4 100644
--- a/external/freetype/ExternalProject_freetype.mk
+++ b/external/freetype/ExternalProject_freetype.mk
@@ -17,7 +17,10 @@ $(call gb_ExternalProject_get_state_target,freetype,build) :
        $(call gb_Trace_StartRange,freetype,EXTERNAL)
        $(call gb_ExternalProject_run,build,\
                $(gb_RUN_CONFIGURE) ./configure \
-                       --disable-shared \
+                       $(if $(filter LINUX,$(OS)), \
+                               --disable-static, \
+                               --disable-shared \
+                       ) \
                        --with-pic \
                        --without-zlib \
                        --without-brotli \
diff --git a/external/freetype/Module_freetype.mk 
b/external/freetype/Module_freetype.mk
index 290014c47dfd..8552511e1674 100644
--- a/external/freetype/Module_freetype.mk
+++ b/external/freetype/Module_freetype.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_Module_Module,freetype))
 $(eval $(call gb_Module_add_targets,freetype,\
        ExternalProject_freetype \
        UnpackedTarball_freetype \
+       $(if $(filter LINUX,$(OS)),ExternalPackage_freetype) \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/freetype/UnpackedTarball_freetype.mk 
b/external/freetype/UnpackedTarball_freetype.mk
index 6f724d1776fc..c4c2da5a28fa 100644
--- a/external/freetype/UnpackedTarball_freetype.mk
+++ b/external/freetype/UnpackedTarball_freetype.mk
@@ -13,6 +13,8 @@ $(eval $(call 
gb_UnpackedTarball_set_tarball,freetype,$(FREETYPE_TARBALL),,freet
 
 $(eval $(call gb_UnpackedTarball_add_patches,freetype,\
        external/freetype/freetype-2.6.5.patch.1 \
+       external/freetype/freetype-fd-hack.patch.0 \
+       external/freetype/libfreetype-bundled-soname.patch.0 \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/freetype/freetype-fd-hack.patch.0 
b/external/freetype/freetype-fd-hack.patch.0
new file mode 100644
index 000000000000..db2bdc9e92f6
--- /dev/null
+++ b/external/freetype/freetype-fd-hack.patch.0
@@ -0,0 +1,53 @@
+# -*- Mode: Diff -*-
+--- src/base/ftsystem.c
++++ src/base/ftsystem.c
+@@ -237,6 +237,8 @@
+                   const char*  filepathname )
+   {
+     FT_FILE*  file;
++    int nFD;
++    int n;
+ 
+ 
+     if ( !stream )
+@@ -257,7 +257,13 @@
+     stream->read               = NULL;
+     stream->close              = NULL;
+ 
+-    file = ft_fopen( filepathname, "rb" );
++    if ( sscanf( filepathname, "/:FD:/%d%n", &nFD, &n ) == 1 && 
filepathname[n] == '\0')
++    {
++      lseek( nFD, 0, SEEK_SET );
++      file = fdopen( dup( nFD ), "rb" );
++    }
++    else
++      file = ft_fopen( filepathname, "rb" );
+     if ( !file )
+     {
+       FT_ERROR(( "FT_Stream_Open:"
+--- builds/unix/ftsystem.c
++++ builds/unix/ftsystem.c
+@@ -249,6 +249,8 @@
+   {
+     int          file;
+     struct stat  stat_buf;
++    int nFD;
++    int n;
+ 
+ 
+     if ( !stream )
+@@ -255,7 +255,13 @@
+       return FT_THROW( Invalid_Stream_Handle );
+ 
+     /* open the file */
+-    file = open( filepathname, O_RDONLY );
++    if ( sscanf( filepathname, "/:FD:/%d%n", &nFD, &n ) == 1 && 
filepathname[n] == '\0')
++    {
++      lseek( nFD, 0, SEEK_SET );
++      file = dup( nFD );
++    }
++    else
++      file = open( filepathname, O_RDONLY );
+     if ( file < 0 )
+     {
+       FT_ERROR(( "FT_Stream_Open:" ));
diff --git a/external/freetype/libfreetype-bundled-soname.patch.0 
b/external/freetype/libfreetype-bundled-soname.patch.0
new file mode 100644
index 000000000000..5b864be562b8
--- /dev/null
+++ b/external/freetype/libfreetype-bundled-soname.patch.0
@@ -0,0 +1,11 @@
+# -*- Mode: Diff -*-
+--- builds/unix/unix-cc.in
++++ builds/unix/unix-cc.in
+@@ -123,6 +123,7 @@
+ LINK_LIBRARY = $(LIBTOOL) --mode=link $(CCraw) -o $@ $(OBJECTS_LIST) \
+                           -rpath $(libdir) -version-info $(version_info) \
+                           $(LDFLAGS) -no-undefined \
++                          -release lo -Wl,-soname 
-Wl,libfreetype-lo.so.6.18.0 \
+                           -export-symbols $(EXPORTS_LIST)
+ 
+ # EOF
diff --git a/external/harfbuzz/ExternalPackage_harfbuzz.mk 
b/external/harfbuzz/ExternalPackage_harfbuzz.mk
new file mode 100644
index 000000000000..bd783c605933
--- /dev/null
+++ b/external/harfbuzz/ExternalPackage_harfbuzz.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_ExternalPackage_ExternalPackage,harfbuzz,harfbuzz))
+
+$(eval $(call gb_ExternalPackage_use_external_project,harfbuzz,harfbuzz))
+
+$(eval $(call 
gb_ExternalPackage_add_file,harfbuzz,$(LIBO_LIB_FOLDER)/libharfbuzz-lo.so.0.20802.0,src/.libs/libharfbuzz-lo.so.0.20802.0))
+$(eval $(call 
gb_ExternalPackage_add_file,harfbuzz,$(LIBO_LIB_FOLDER)/libharfbuzz-lo.so.0,src/.libs/libharfbuzz-lo.so.0))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk 
b/external/harfbuzz/ExternalProject_harfbuzz.mk
index caf6bcd5f922..ead4325d8cf4 100644
--- a/external/harfbuzz/ExternalProject_harfbuzz.mk
+++ b/external/harfbuzz/ExternalProject_harfbuzz.mk
@@ -28,8 +28,13 @@ $(call gb_ExternalProject_get_state_target,harfbuzz,build) :
                GRAPHITE2_CFLAGS="$(GRAPHITE_CFLAGS)" \
                GRAPHITE2_LIBS="$(GRAPHITE_LIBS)" \
                $(gb_RUN_CONFIGURE) ./configure \
-                       --enable-static \
-                       --disable-shared \
+                       $(if $(filter LINUX,$(OS)), \
+                               --enable-shared \
+                               --disable-static \
+                       , \
+                               --enable-static \
+                               --disable-shared \
+                       ) \
                        --disable-gtk-doc \
                        --with-pic \
                        --with-icu=builtin \
diff --git a/external/harfbuzz/Module_harfbuzz.mk 
b/external/harfbuzz/Module_harfbuzz.mk
index ffbadd7107a7..17e09865b16d 100644
--- a/external/harfbuzz/Module_harfbuzz.mk
+++ b/external/harfbuzz/Module_harfbuzz.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_Module_Module,harfbuzz))
 $(eval $(call gb_Module_add_targets,harfbuzz,\
        ExternalProject_harfbuzz \
        UnpackedTarball_harfbuzz \
+       $(if $(filter LINUX,$(OS)),ExternalPackage_harfbuzz) \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/harfbuzz/UnpackedTarball_harfbuzz.mk 
b/external/harfbuzz/UnpackedTarball_harfbuzz.mk
index 83df909aaf99..a8a3b57eb4a5 100644
--- a/external/harfbuzz/UnpackedTarball_harfbuzz.mk
+++ b/external/harfbuzz/UnpackedTarball_harfbuzz.mk
@@ -20,6 +20,10 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,harfbuzz,0))
 #   be negative":
 $(eval $(call gb_UnpackedTarball_add_patches,harfbuzz, \
     external/harfbuzz/negativeadvance.patch \
+    $(if $(filter LINUX,$(OS)), \
+        external/harfbuzz/libharfbuzz-bundled-soname.patch.0 \
+        external/harfbuzz/harfbuzz-fd-hack.patch.0 \
+    ) \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/harfbuzz/harfbuzz-fd-hack.patch.0 
b/external/harfbuzz/harfbuzz-fd-hack.patch.0
new file mode 100644
index 000000000000..1cc5820fd49c
--- /dev/null
+++ b/external/harfbuzz/harfbuzz-fd-hack.patch.0
@@ -0,0 +1,24 @@
+# -*- Mode: Diff -*-
+--- src/hb-blob.cc
++++ src/hb-blob.cc
+@@ -737,7 +737,19 @@
+   char *data = (char *) hb_malloc (allocated);
+   if (unlikely (!data)) return nullptr;
+ 
+-  FILE *fp = fopen (file_name, "rb");
++  FILE *fp;
++  int nFD;
++  int n;
++  if (sscanf (file_name, "/:FD:/%d%n", &nFD, &n) == 1 && file_name[n] == '\0')
++  {
++    lseek (nFD, 0, SEEK_SET);
++    fp = fdopen (dup (nFD), "rb");
++  }
++  else
++  {
++    fp = fopen (file_name, "rb");
++  }
++
+   if (unlikely (!fp)) goto fread_fail_without_close;
+ 
+   while (!feof (fp))
diff --git a/external/harfbuzz/libharfbuzz-bundled-soname.patch.0 
b/external/harfbuzz/libharfbuzz-bundled-soname.patch.0
new file mode 100644
index 000000000000..33c3dd9728dc
--- /dev/null
+++ b/external/harfbuzz/libharfbuzz-bundled-soname.patch.0
@@ -0,0 +1,24 @@
+# -*- Mode: Diff -*-
+--- src/Makefile.in
++++ src/Makefile.in
+@@ -525,7 +525,7 @@
+ libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS)
+ libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS)
+ libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(CODE_COVERAGE_CFLAGS)
+-libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) 
$(CODE_COVERAGE_LDFLAGS)
++libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) 
$(CODE_COVERAGE_LDFLAGS) -export-dynamic -release lo
+ libharfbuzz_la_LIBADD = $(HBLIBS)
+ EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
+ pkginclude_HEADERS = $(HBHEADERS) $(HB_SUBSET_headers) \
+--- src/hb-common.h
++++ src/hb-common.h
+@@ -34,7 +34,7 @@
+ #define HB_COMMON_H
+ 
+ #ifndef HB_EXTERN
+-#define HB_EXTERN extern
++#define HB_EXTERN __attribute__((__visibility__("default")))
+ #endif
+ 
+ #ifndef HB_BEGIN_DECLS
+
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 18748053029e..4a4c0bf74184 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1124,7 +1124,18 @@ int CountTTCFonts(const char* fname)
 {
     int nFonts = 0;
     sal_uInt8 buffer[12];
-    FILE* fd = fopen(fname, "rb");
+    FILE* fd;
+#ifdef LINUX
+    int nFD;
+    int n;
+    if (sscanf(fname, "/:FD:/%d%n", &nFD, &n) == 1 && fname[n] == '\0')
+    {
+        lseek(nFD, 0, SEEK_SET);
+        fd = fdopen(dup(nFD), "rb");
+    }
+    else
+#endif
+        fd = fopen(fname, "rb");
     if( fd ) {
         if (fread(buffer, 1, 12, fd) == 12) {
             if(GetUInt32(buffer, 0) == T_ttcf )
@@ -1155,7 +1166,15 @@ SFErrCodes OpenTTFontFile(const char* fname, sal_uInt32 
facenum, TrueTypeFont**
         goto cleanup;
     }
 
-    fd = open(fname, O_RDONLY);
+    int nFD;
+    int n;
+    if (sscanf(fname, "/:FD:/%d%n", &nFD, &n) == 1 && fname[n] == '\0')
+    {
+        lseek(nFD, 0, SEEK_SET);
+        fd = dup(nFD);
+    }
+    else
+        fd = open(fname, O_RDONLY);
 
     if (fd == -1) {
         ret = SFErrCodes::BadFile;
diff --git a/vcl/unx/generic/fontmanager/fontmanager.cxx 
b/vcl/unx/generic/fontmanager/fontmanager.cxx
index 86b5b1b435e3..5b020e764d7e 100644
--- a/vcl/unx/generic/fontmanager/fontmanager.cxx
+++ b/vcl/unx/generic/fontmanager/fontmanager.cxx
@@ -182,25 +182,38 @@ std::vector<PrintFontManager::PrintFont> 
PrintFontManager::analyzeFontFile( int
 
     OString aFullPath = aDir + "/" + rFontFile;
 
-    // #i1872# reject unreadable files
-    if( access( aFullPath.getStr(), R_OK ) )
-        return aNewFonts;
-
-    bool bSupported = false;
-    if (pFormat)
+    bool bSupported;
+    bool bHack = false;
+    int nFD;
+    int n;
+    if (sscanf(aFullPath.getStr(), "/:FD:/%d%n", &nFD, &n) == 1 && 
aFullPath.getStr()[n] == '\0')
     {
-        if (!strcmp(pFormat, "TrueType") ||
-            !strcmp(pFormat, "CFF"))
-            bSupported = true;
+        // Hack, pathname that actually means we will use a pre-opened file 
descriptor
+        bSupported = true;
+        bHack = true;
     }
-    if (!bSupported)
+    else
     {
-        OString aExt( rFontFile.copy( rFontFile.lastIndexOf( '.' )+1 ) );
-        if( aExt.equalsIgnoreAsciiCase("ttf")
-             ||  aExt.equalsIgnoreAsciiCase("ttc")
-             ||  aExt.equalsIgnoreAsciiCase("tte")   // #i33947# for Gaiji 
support
-             ||  aExt.equalsIgnoreAsciiCase("otf") ) // check for TTF- and 
PS-OpenType too
-            bSupported = true;
+        // #i1872# reject unreadable files
+        if( access( aFullPath.getStr(), R_OK ) )
+            return aNewFonts;
+
+        bSupported = false;
+        if (pFormat)
+        {
+            if (!strcmp(pFormat, "TrueType") ||
+                !strcmp(pFormat, "CFF"))
+                bSupported = true;
+        }
+        if (!bSupported)
+        {
+            OString aExt( rFontFile.copy( rFontFile.lastIndexOf( '.' )+1 ) );
+            if( aExt.equalsIgnoreAsciiCase("ttf")
+                 ||  aExt.equalsIgnoreAsciiCase("ttc")
+                 ||  aExt.equalsIgnoreAsciiCase("tte")   // #i33947# for Gaiji 
support
+                 ||  aExt.equalsIgnoreAsciiCase("otf") ) // check for TTF- and 
PS-OpenType too
+                bSupported = true;
+        }
     }
 
     if (bSupported)
@@ -211,33 +224,36 @@ std::vector<PrintFontManager::PrintFont> 
PrintFontManager::analyzeFontFile( int
         {
             SAL_INFO("vcl.fonts", "ttc: " << aFullPath << " contains " << 
nLength << " fonts");
 
-            sal_uInt64 fileSize = 0;
-
-            OUString aURL;
-            if 
(osl::File::getFileURLFromSystemPath(OStringToOUString(aFullPath, 
osl_getThreadTextEncoding()),
-                aURL) == osl::File::E_None)
+            if (!bHack)
             {
-                osl::File aFile(aURL);
-                if (aFile.open(osl_File_OpenFlag_Read | 
osl_File_OpenFlag_NoLock) == osl::File::E_None)
+                sal_uInt64 fileSize = 0;
+
+                OUString aURL;
+                if 
(osl::File::getFileURLFromSystemPath(OStringToOUString(aFullPath, 
osl_getThreadTextEncoding()),
+                    aURL) == osl::File::E_None)
                 {
-                    osl::DirectoryItem aItem;
-                    if (osl::DirectoryItem::get(aURL, aItem) == 
osl::File::E_None)
+                    osl::File aFile(aURL);
+                    if (aFile.open(osl_File_OpenFlag_Read | 
osl_File_OpenFlag_NoLock) == osl::File::E_None)
                     {
-                        osl::FileStatus aFileStatus( 
osl_FileStatus_Mask_FileSize );
-                        if (aItem.getFileStatus(aFileStatus) == 
osl::File::E_None)
-                            fileSize = aFileStatus.getFileSize();
+                        osl::DirectoryItem aItem;
+                        if (osl::DirectoryItem::get(aURL, aItem) == 
osl::File::E_None)
+                        {
+                            osl::FileStatus aFileStatus( 
osl_FileStatus_Mask_FileSize );
+                            if (aItem.getFileStatus(aFileStatus) == 
osl::File::E_None)
+                                fileSize = aFileStatus.getFileSize();
+                        }
                     }
                 }
-            }
 
-            //Feel free to calc the exact max possible number of fonts a file
-            //could contain given its physical size. But this will clamp it to
-            //a sane starting point
-            //http://processingjs.nihongoresources.com/the_smallest_font/
-            //https://github.com/grzegorzrolek/null-ttf
-            const int nMaxFontsPossible = fileSize / 528;
-            if (nLength > nMaxFontsPossible)
-                nLength = nMaxFontsPossible;
+                //Feel free to calc the exact max possible number of fonts a 
file
+                //could contain given its physical size. But this will clamp 
it to
+                //a sane starting point
+                //http://processingjs.nihongoresources.com/the_smallest_font/
+                //https://github.com/grzegorzrolek/null-ttf
+                const int nMaxFontsPossible = fileSize / 528;
+                if (nLength > nMaxFontsPossible)
+                    nLength = nMaxFontsPossible;
+            }
 
             for( int i = 0; i < nLength; i++ )
             {
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx 
b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index b19b6bb96446..1cf5cbd47143 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -102,7 +102,16 @@ bool FreetypeFontFile::Map()
     if (mnRefCount++ == 0)
     {
         const char* pFileName = maNativeFileName.getStr();
-        int nFile = open( pFileName, O_RDONLY );
+        int nFile;
+        int nFD;
+        int n;
+        if( sscanf( pFileName, "/:FD:/%d%n", &nFD, &n ) == 1 && pFileName[n] 
== '\0' )
+        {
+            lseek( nFD, 0, SEEK_SET );
+            nFile = dup( nFD );
+        }
+        else
+            nFile = open( pFileName, O_RDONLY );
         if( nFile < 0 )
         {
             SAL_WARN("vcl.unx.freetype", "open('" << maNativeFileName << "') 
failed: " << strerror(errno));
@@ -125,6 +134,8 @@ bool FreetypeFontFile::Map()
             SAL_WARN("vcl.unx.freetype", "mmap of '" << maNativeFileName << "' 
failed: " << strerror(errno));
             mpFileMap = nullptr;
         }
+        else
+            SAL_INFO("vcl.unx.freetype", "mmap'ed '" << maNativeFileName << "' 
successfully");
         close( nFile );
     }
 

Reply via email to