From 547e40b114f44c528107afd28135fcc964c45619 Mon Sep 17 00:00:00 2001 From: Arthur Norman Date: Tue, 7 Nov 2017 17:41:11 +0100 Subject: [PATCH 01/17] Add support for loading fonts from files. wxFont::AddPrivateFont() can now be used to load a font from a file for the applications private use. Update the font sample to show this. Closes #13568. --- docs/changes.txt | 1 + docs/doxygen/mainpages/const_cpp.h | 1 + docs/doxygen/overviews/font.h | 15 +++++ include/wx/font.h | 6 ++ include/wx/gtk/font.h | 4 ++ include/wx/msw/font.h | 2 + include/wx/osx/font.h | 2 + interface/wx/font.h | 38 ++++++++++++ samples/font/Makefile.in | 16 ++++- samples/font/font.bkl | 7 +++ samples/font/font.cpp | 57 +++++++++++++++++- samples/font/makefile.bcc | 6 +- samples/font/makefile.gcc | 8 ++- samples/font/makefile.vc | 6 +- samples/font/wxprivate.ttf | Bin 0 -> 21428 bytes src/common/fontcmn.cpp | 16 +++++ src/gtk/font.cpp | 60 +++++++++++++++++++ src/msw/graphics.cpp | 91 ++++++++++++++++++++++++++++- src/osx/fontutil.cpp | 38 ++++++++++++ 19 files changed, 366 insertions(+), 8 deletions(-) create mode 100644 samples/font/wxprivate.ttf diff --git a/docs/changes.txt b/docs/changes.txt index 5e464c7632..b35ec1a63f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -109,6 +109,7 @@ All (GUI): - Allow wxWebView::RunScript() return values (Jose Lorenzo, GSoC 2017). - Allow using fractional pen widths with wxGraphicsContext (Adrien Tétar). +- Add support for loading fonts from external files (Arthur Norman). - Improve wxSVGFileDC to support more of wxDC API (Maarten Bent). - Add support for wxAuiManager and wxAuiPaneInfo to XRC (Andrea Zanellato). - Add support for wxSL_MIN_MAX_LABELS and wxSL_VALUE_LABEL to XRC (ousnius). diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index 1756d18a82..3fd074fb70 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -188,6 +188,7 @@ Currently the following symbols exist: @itemdef{wxHAS_IMAGES_IN_RESOURCES, Defined if Windows resource files or OS/2 resource files are available on the current platform.} @itemdef{wxHAS_POWER_EVENTS, Defined if wxPowerEvent are ever generated on the current platform.} +@itemdef{wxHAS_PRIVATE_FONTS, Defined if wxFont::AddPrivateFont() is implemented.} @itemdef{wxHAS_RADIO_MENU_ITEMS, Defined if the current port supports radio menu items (see wxMenu::AppendRadioItem).} @itemdef{wxHAS_RAW_BITMAP, Defined if direct access to bitmap data using the classes in @c wx/rawbmp.h is supported.} diff --git a/docs/doxygen/overviews/font.h b/docs/doxygen/overviews/font.h index d303c3960c..49635f37ec 100644 --- a/docs/doxygen/overviews/font.h +++ b/docs/doxygen/overviews/font.h @@ -75,4 +75,19 @@ implemented for Windows and Unix (GTK+ and Motif) ports only, all the methods are available for all the ports and should be used to make your program work correctly when they are implemented later. +@section overview_font_privateinfo Private font information + +Sometimes an application needs fonts that are not globally installed on the +system. On Macintosh/OSX this can be arranged by placing the desired fonts +within the Application Bundle in Contents/Resources/Fonts and using +the ATSApplicationFontsPath key to point there. The full details of the +procedure there can be found as OSX developer resources. For the GTK+ and +Windows ports it is possible to add TrueType fonts at run-time using +a sequence of calls to wxFont::AddPrivateFont() to give the names of files +containing font data, followed by a call to wxFont::ActivatePrivateFonts() +to complete the process of making the fonts available. These functions +return false if they fail. They should be called just once before any +graphics contexts have been created or other activity liable to use fonts +has happened. + */ diff --git a/include/wx/font.h b/include/wx/font.h index 3e0ee14102..f3731179f8 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -328,6 +328,12 @@ public: // from the string representation of wxNativeFontInfo static wxFont *New(const wxString& strNativeFontDesc); + // These functions can be used to load private fonts if supported by this + // platform (wxHAS_PRIVATE_FONTS is defined): first add one or more files + // and then activate all of them at once. + static bool AddPrivateFont(const wxString& filename); + static bool ActivatePrivateFonts(); + // comparison bool operator==(const wxFont& font) const; bool operator!=(const wxFont& font) const { return !(*this == font); } diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h index 4d1220617d..669055c2c3 100644 --- a/include/wx/gtk/font.h +++ b/include/wx/gtk/font.h @@ -118,4 +118,8 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; +#ifndef __WXMSW__ + #define wxHAS_PRIVATE_FONTS 1 +#endif + #endif // _WX_GTK_FONT_H_ diff --git a/include/wx/msw/font.h b/include/wx/msw/font.h index eec24baedb..16dae838a9 100644 --- a/include/wx/msw/font.h +++ b/include/wx/msw/font.h @@ -169,4 +169,6 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; +#define wxHAS_PRIVATE_FONTS 1 + #endif // _WX_FONT_H_ diff --git a/include/wx/osx/font.h b/include/wx/osx/font.h index fcd82013f5..bd29cdf538 100644 --- a/include/wx/osx/font.h +++ b/include/wx/osx/font.h @@ -167,4 +167,6 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; +#define wxHAS_PRIVATE_FONTS 1 + #endif // _WX_FONT_H_ diff --git a/interface/wx/font.h b/interface/wx/font.h index b16e12b507..392849b2d3 100644 --- a/interface/wx/font.h +++ b/interface/wx/font.h @@ -664,6 +664,44 @@ public: const wxNativeFontInfo *GetNativeFontInfo() const; + /** + Specify the name of a file containing a TrueType font to be + made available to the current application. + + This method can be used to allow this application to use the font from + the given file even if it is not globally installed on the system. + + Under OS X this method actually doesn't do anything other than check + for the existence of the file in the "Fonts" subdirectory of the + application bundle "Resources" directory. You are responsible for + actually making the font file available in this directory and setting + @c ATSApplicationFontsPath to @c Fonts value in your @c Info.plist + file. See also wxStandardPaths::GetResourcesDir(). + + Notice that this method must be called before any graphics contexts + have been created. + + Currently this method is implemented for all major platforms but you + may also test for @c wxHAS_PRIVATE_FONTS preprocessor symbol: if it is + not defined, this function and ActivatePrivatefonts() are not + implemented at all and always simply return false. + + @return @true if the font was added and ActivatePrivatefonts() should + be called next or @false if adding it failed. + + @since 2.9.5 + */ + static bool AddPrivateFont(const wxString& filename); + + /** + Make all fonts registered by AddPrivateFont() actually available. + + @return @true if the private fonts can now be used or @false on error. + + @since 2.9.5 + */ + static bool ActivatePrivatefonts(); + /** Gets the point size. diff --git a/samples/font/Makefile.in b/samples/font/Makefile.in index d4b565c83e..3291284be0 100644 --- a/samples/font/Makefile.in +++ b/samples/font/Makefile.in @@ -128,7 +128,7 @@ COND_wxUSE_REGEX_builtin___LIB_REGEX_p = \ ### Targets: ### -all: font$(EXEEXT) $(__font_bundle___depname) +all: font$(EXEEXT) $(__font_bundle___depname) data install: @@ -171,6 +171,18 @@ font$(EXEEXT): $(FONT_OBJECTS) $(__font___win32rc) @COND_PLATFORM_MACOSX_1@font_bundle: $(____font_BUNDLE_TGT_REF_DEP) +data: + @mkdir -p . + @for f in wxprivate.ttf; do \ + if test ! -f ./$$f -a ! -d ./$$f ; \ + then x=yep ; \ + else x=`find $(srcdir)/$$f -newer ./$$f -print` ; \ + fi; \ + case "$$x" in ?*) \ + cp -pRf $(srcdir)/$$f . ;; \ + esac; \ + done + font_sample_rc.o: $(srcdir)/../../samples/sample.rc $(WINDRES) -i$< -o$@ --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) --include-dir $(srcdir) $(__DLLFLAG_p_1) --include-dir $(srcdir)/../../samples $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include @@ -181,4 +193,4 @@ font_font.o: $(srcdir)/font.cpp # Include dependency info, if present: @IF_GNU_MAKE@-include ./.deps/*.d -.PHONY: all install uninstall clean distclean font_bundle +.PHONY: all install uninstall clean distclean font_bundle data diff --git a/samples/font/font.bkl b/samples/font/font.bkl index cb88a72e12..bfa8333cb2 100644 --- a/samples/font/font.bkl +++ b/samples/font/font.bkl @@ -9,4 +9,11 @@ base + + + wxprivate.ttf + + + + diff --git a/samples/font/font.cpp b/samples/font/font.cpp index ed31b2dc26..b02544644e 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -29,6 +29,7 @@ #include "wx/fontmap.h" #include "wx/encconv.h" #include "wx/splitter.h" +#include "wx/stdpaths.h" #include "wx/textfile.h" #include "wx/settings.h" @@ -130,6 +131,7 @@ public: void OnSetFamily(wxCommandEvent& event); void OnSetFaceName(wxCommandEvent& event); void OnSetEncoding(wxCommandEvent& event); + void OnPrivateFont(wxCommandEvent& event); protected: bool DoEnumerateFamilies(bool fixedWidthOnly, @@ -212,6 +214,8 @@ enum Font_SetFamily, Font_SetFaceName, Font_SetEncoding, + + Font_Private, Font_Max }; @@ -265,6 +269,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies) EVT_MENU(Font_EnumFixedFamilies, MyFrame::OnEnumerateFixedFamilies) EVT_MENU(Font_EnumEncodings, MyFrame::OnEnumerateEncodings) + EVT_MENU(Font_Private, MyFrame::OnPrivateFont) wxEND_EVENT_TABLE() // Create a new application object: this macro will allow wxWidgets to create @@ -287,6 +292,7 @@ bool MyApp::OnInit() { if ( !wxApp::OnInit() ) return false; + wxString privfont = argv[0].BeforeLast('/'); // Create the main application window MyFrame *frame = new MyFrame(wxT("Font wxWidgets demo"), @@ -381,7 +387,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) wxT("Default font for user interface objects such as menus and dialog boxes. ")); menuSelect->Append(Font_SystemSettings, wxT("System fonts"), menuSettingFonts); - menuSelect->AppendSeparator(); menuSelect->Append(Font_EnumFamilies, wxT("Enumerate font &families\tCtrl-F")); menuSelect->Append(Font_EnumFixedFamilies, @@ -392,6 +397,42 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) wxT("Find font for en&coding...\tCtrl-C"), wxT("Find font families for given encoding")); +#ifdef wxHAS_PRIVATE_FONTS + // Try to use a private font, under most platforms we just look for it in + // the current directory but under OS X it must be in a specific location + // so look for it there. + // + // For OS X you also need to ensure that you actually do put wxprivate.ttf + // in font.app/Contents/Resources/Fonts and add the following snippet + // + // + // + // ... + // ATSApplicationFontsPath + // Fonts + // ... + // + // + // + // to your font.app/Contents/Info.plist. + + wxString privfont; +#ifdef __WXOSX__ + privfont << wxStandardPaths::Get().GetResourcesDir() << "/Fonts/"; +#endif + privfont << "wxprivate.ttf"; + + if ( wxFont::AddPrivateFont(privfont) && + wxFont::ActivatePrivateFonts() ) + { + menuSelect->AppendSeparator(); + menuSelect->Append(Font_Private, + "Select private font", + "Select a font available only in this application"); + } +#endif // wxHAS_PRIVATE_FONTS + + // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar; menuBar->Append(menuFile, wxT("&File")); @@ -873,6 +914,20 @@ void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event)) } } +void MyFrame::OnPrivateFont(wxCommandEvent& WXUNUSED(event)) +{ + wxFont font(GetCanvas()->GetTextFont()); + if (font.SetFaceName("wxprivate")) + { + wxASSERT_MSG( font.IsOk(), wxT("The font should now be valid")) ; + DoChangeFont(font); + } + else + { + wxLogError("Failed to use private font."); + } +} + void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { // true is to force the frame to close diff --git a/samples/font/makefile.bcc b/samples/font/makefile.bcc index 083765af16..65f9a92a1f 100644 --- a/samples/font/makefile.bcc +++ b/samples/font/makefile.bcc @@ -213,7 +213,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\font.exe +all: $(OBJS)\font.exe data clean: -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -231,6 +231,10 @@ $(OBJS)\font.exe: $(FONT_OBJECTS) $(OBJS)\font_sample.res c0w32.obj $(FONT_OBJECTS),$@,, $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) ole2w32.lib oleacc.lib import32.lib cw32$(__THREADSFLAG_5)$(__RUNTIME_LIBS_8).lib,, $(OBJS)\font_sample.res | +data: + if not exist $(OBJS) mkdir $(OBJS) + for %f in (wxprivate.ttf) do if not exist $(OBJS)\%f copy .\%f $(OBJS) + $(OBJS)\font_sample.res: .\..\..\samples\sample.rc brcc32 -32 -r -fo$@ -i$(BCCDIR)\include -d__WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) -i$(SETUPHDIR) -i.\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_1_p) -i. $(__DLLFLAG_p_1) -i.\..\..\samples -i$(BCCDIR)\include\windows\sdk -dNOPCH .\..\..\samples\sample.rc diff --git a/samples/font/makefile.gcc b/samples/font/makefile.gcc index bcad6221d1..47f208ff18 100644 --- a/samples/font/makefile.gcc +++ b/samples/font/makefile.gcc @@ -210,7 +210,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\font.exe +all: $(OBJS)\font.exe data clean: -if exist $(OBJS)\*.o del $(OBJS)\*.o @@ -220,13 +220,17 @@ clean: $(OBJS)\font.exe: $(FONT_OBJECTS) $(OBJS)\font_sample_rc.o $(CXX) -o $@ $(FONT_OBJECTS) $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lwsock32 -lwininet -loleacc +data: + if not exist $(OBJS) mkdir $(OBJS) + for %%f in (wxprivate.ttf) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS) + $(OBJS)\font_sample_rc.o: ./../../samples/sample.rc $(WINDRES) -i$< -o$@ --define __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) --include-dir $(SETUPHDIR) --include-dir ./../../include $(__CAIRO_INCLUDEDIR_p) --include-dir . $(__DLLFLAG_p_1) --include-dir ./../../samples --define NOPCH $(OBJS)\font_font.o: ./font.cpp $(CXX) -c -o $@ $(FONT_CXXFLAGS) $(CPPDEPS) $< -.PHONY: all clean +.PHONY: all clean data SHELL := $(COMSPEC) diff --git a/samples/font/makefile.vc b/samples/font/makefile.vc index 10c1cccd58..431edcac5a 100644 --- a/samples/font/makefile.vc +++ b/samples/font/makefile.vc @@ -339,7 +339,7 @@ $(OBJS): ### Targets: ### -all: $(OBJS)\font.exe +all: $(OBJS)\font.exe data clean: -if exist $(OBJS)\*.obj del $(OBJS)\*.obj @@ -354,6 +354,10 @@ $(OBJS)\font.exe: $(FONT_OBJECTS) $(OBJS)\font_sample.res $(FONT_OBJECTS) $(FONT_RESOURCES) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib wsock32.lib wininet.lib << +data: + if not exist $(OBJS) mkdir $(OBJS) + for %f in (wxprivate.ttf) do if not exist $(OBJS)\%f copy .\%f $(OBJS) + $(OBJS)\font_sample.res: .\..\..\samples\sample.rc rc /fo$@ /d WIN32 $(____DEBUGRUNTIME_3_p_1) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_1) /d __WXMSW__ $(__WXUNIV_DEFINE_p_1) $(__DEBUG_DEFINE_p_1) $(__NDEBUG_DEFINE_p_1) $(__EXCEPTIONS_DEFINE_p_1) $(__RTTI_DEFINE_p_1) $(__THREAD_DEFINE_p_1) $(__UNICODE_DEFINE_p_1) /i $(SETUPHDIR) /i .\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_1_p) /i . $(__DLLFLAG_p_1) /d _WINDOWS /i .\..\..\samples /d NOPCH .\..\..\samples\sample.rc diff --git a/samples/font/wxprivate.ttf b/samples/font/wxprivate.ttf new file mode 100644 index 0000000000000000000000000000000000000000..82d77fe5f3bd0fa3ed78eb5ce51cf9aae94c042a GIT binary patch literal 21428 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 z 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 literal 0 HcmV?d00001 diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index ae9b82607f..f17d045167 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -1137,4 +1137,20 @@ bool wxFromString(const wxString& str, wxFontBase *font) return font->SetNativeFontInfo(str); } +#ifndef wxHAS_PRIVATE_FONTS +// Adding private fonts is not supported on this platform, so provide the +// functions that would be used, but make them no-ops that return a code +// that indicates failure. + +bool wxFontBase::AddPrivateFont(const wxString& WXUNUSED(filename)) +{ + return false; +} + +bool wxFontBase::ActivatePrivateFonts() +{ + return false; +} + +#endif // !wxHAS_PRIVATE_FONTS diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 54ec1b403c..297c567e25 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -31,6 +31,11 @@ #include "wx/gtk/private.h" +#ifdef GDK_WINDOWING_X11 + #include + #include +#endif + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -551,3 +556,58 @@ bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const return true; } + + +// ---------------------------------------------------------------------------- +// Support for adding private fonts +// ---------------------------------------------------------------------------- + +#ifdef wxHAS_PRIVATE_FONTS + +namespace +{ + FcConfig* gs_fcConfig = NULL; +} + +bool wxFontBase::AddPrivateFont(const wxString& filename) +{ + if ( !gs_fcConfig ) + { + gs_fcConfig = FcConfigGetCurrent(); + if ( !gs_fcConfig ) + { + gs_fcConfig = FcConfigCreate(); + if ( !gs_fcConfig ) + { + wxLogError(_("Failed to add custom font \"%s\" as " + "font configuration object creation failed."), + filename); + return false; + } + } + } + + if ( !FcConfigAppFontAddFile(gs_fcConfig, + reinterpret_cast( + static_cast(filename.utf8_str()) + )) ) + { + wxLogError(_("Failed to add custom font \"%s\"."), filename); + return false; + } + + return true; +} + +bool wxFontBase::ActivatePrivateFonts() +{ + if ( !FcConfigSetCurrent(gs_fcConfig) ) + { + wxLogError(_("Failed to update current font configuration.")); + return false; + } + + return true; +} + +#endif // wxHAS_PRIVATE_FONTS diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index b518dbdd99..fd5957e59a 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -37,6 +37,7 @@ #include "wx/dcprint.h" #endif +#include "wx/filename.h" #include "wx/stack.h" #include "wx/private/graphics.h" @@ -959,6 +960,47 @@ wxGDIPlusBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo, SetGradientStops(brush, stops, true); } +//----------------------------------------------------------------------------- +// Support for adding private fonts +//----------------------------------------------------------------------------- + +namespace +{ + +wxArrayString gs_privateFontFileNames; +Gdiplus::PrivateFontCollection* gs_privateFonts = NULL; +Gdiplus::FontFamily* gs_pFontFamily = NULL; + +} // anonymous namespace + +bool wxFontBase::AddPrivateFont(const wxString& filename) +{ + if ( !wxFileName::FileExists(filename) ) + { + wxLogError(_("Font file \"%s\" doesn't exist."), filename); + return false; + } + + gs_privateFontFileNames.Add(filename); + return true; +} + +bool wxFontBase::ActivatePrivateFonts() +{ + const int n = gs_privateFontFileNames.size(); + for ( int i = 0 ; i < n; i++ ) + { + const wxString& fname = gs_privateFontFileNames[i]; + if ( !AddFontResourceEx(fname.t_str(), FR_PRIVATE, 0) ) + { + wxLogSysError(_("Font file \"%s\" couldn't be loaded"), + fname); + } + } + + return true; +} + //----------------------------------------------------------------------------- // wxGDIPlusFont implementation //----------------------------------------------------------------------------- @@ -970,7 +1012,31 @@ wxGDIPlusFontData::Init(const wxString& name, const wxColour& col, Unit fontUnit) { - m_font = new Font(name.wc_str(), size, style, fontUnit); + // If the user has registered any private fonts, they should be used in + // preference to any system-wide ones. + m_font = NULL; + if ( gs_privateFonts ) + { + const int count = gs_privateFonts->GetFamilyCount(); + + // We should find all the families, i.e. "found" should be "count". + int found = 0; + gs_privateFonts->GetFamilies(count, gs_pFontFamily, &found); + + for ( int j = 0 ; j < found; j++ ) + { + wchar_t familyName[LF_FACESIZE]; + int rc = gs_pFontFamily[j].GetFamilyName(familyName); + if ( rc == 0 && lstrcmp(name, familyName) == 0 ) + { + m_font = new Font(&gs_pFontFamily[j], size, style, fontUnit); + break; + } + } + } + + if ( !m_font ) + m_font = new Font(name, size, style, fontUnit); m_textBrush = new SolidBrush(wxColourToColor(col)); } @@ -2275,6 +2341,20 @@ void wxGDIPlusRenderer::Load() { wxLogTrace("gdiplus", "successfully initialized GDI+"); m_loaded = 1; + + // Make private fonts available to GDI+, if any. + const int n = gs_privateFontFileNames.size(); + if ( n ) + { + gs_privateFonts = new Gdiplus::PrivateFontCollection(); + for ( int i = 0 ; i < n; i++ ) + { + const wxString& fname = gs_privateFontFileNames[i]; + gs_privateFonts->AddFontFile(fname.t_str()); + } + + gs_pFontFamily = new Gdiplus::FontFamily[n]; + } } else { @@ -2289,6 +2369,15 @@ void wxGDIPlusRenderer::Unload() { GdiplusShutdown(m_gditoken); m_gditoken = 0; + + if ( gs_privateFonts ) + { + delete gs_privateFonts; + gs_privateFonts = NULL; + + delete[] gs_pFontFamily; + gs_pFontFamily = NULL; + } } m_loaded = -1; // next Load() will try again } diff --git a/src/osx/fontutil.cpp b/src/osx/fontutil.cpp index 5828657448..dd67c6322f 100644 --- a/src/osx/fontutil.cpp +++ b/src/osx/fontutil.cpp @@ -24,6 +24,8 @@ #include "wx/fontutil.h" #include "wx/fontmap.h" #include "wx/encinfo.h" +#include "wx/filename.h" +#include "wx/stdpaths.h" #include "wx/tokenzr.h" @@ -63,6 +65,42 @@ wxString wxNativeEncodingInfo::ToString() const return s; } +// ---------------------------------------------------------------------------- +// Private Fonts +// ---------------------------------------------------------------------------- + +// On OSX one can provide private fonts simply by putting the font files in +// with the resources in your application bundle. So the API for adding fonts +// does not do anything except checking that the file you pass to it actually +// does exist and is in the correct directory. + +bool wxFontBase::AddPrivateFont(const wxString& filename) +{ + wxFileName fn(filename); + if ( !fn.FileExists() ) + { + wxLogError(_("Font file \"%s\" doesn't exist."), filename); + return false; + } + + wxString fontsDir; + fontsDir << wxStandardPaths::Get().GetResourcesDir() << "/Fonts"; + if ( fn.GetPath() != fontsDir ) + { + wxLogError(_("Font file \"%s\" cannot be used as it is not inside " + "the font directory \"%s\"."), filename, fontsDir); + return false; + } + + return true; +} + +bool wxFontBase::ActivatePrivateFonts() +{ + // Nothing to do here. + return true; +} + // ---------------------------------------------------------------------------- // helper functions // ---------------------------------------------------------------------------- From a7a59a263d8221a1b2e0b15cc01f7b95dd66dc55 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 17:46:25 +0100 Subject: [PATCH 02/17] Update the version when private font support was added It will be 3.1.1 and not 2.9.5 as originally planned. --- interface/wx/font.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/wx/font.h b/interface/wx/font.h index 392849b2d3..7bc5c14cec 100644 --- a/interface/wx/font.h +++ b/interface/wx/font.h @@ -689,7 +689,7 @@ public: @return @true if the font was added and ActivatePrivatefonts() should be called next or @false if adding it failed. - @since 2.9.5 + @since 3.1.1 */ static bool AddPrivateFont(const wxString& filename); @@ -698,7 +698,7 @@ public: @return @true if the private fonts can now be used or @false on error. - @since 2.9.5 + @since 3.1.1 */ static bool ActivatePrivatefonts(); From 4145a30e06296b1a6165930ac371ba20c5e8fc7e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 17:58:50 +0100 Subject: [PATCH 03/17] Report errors if using private font fails in the font sample Give more information instead of just silently not showing the corresponding menu item. --- samples/font/font.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/samples/font/font.cpp b/samples/font/font.cpp index b02544644e..baa7f0b054 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -422,8 +422,15 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) #endif privfont << "wxprivate.ttf"; - if ( wxFont::AddPrivateFont(privfont) && - wxFont::ActivatePrivateFonts() ) + if ( !wxFont::AddPrivateFont(privfont) ) + { + wxLogWarning("Failed to add private font from \"%s\"", privfont); + } + else if ( !wxFont::ActivatePrivateFonts() ) + { + wxLogWarning("Failed to activate the private fonts"); + } + else { menuSelect->AppendSeparator(); menuSelect->Append(Font_Private, From 149807db263929d58b5805ad6534ffaa37aff72b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 18:02:58 +0100 Subject: [PATCH 04/17] Move wxMSW wxFont private font methods to src/msw/font.cpp This ensures that they will be defined and work even when building with wxUSE_GRAPHICS_CONTEXT==0 (as can happen even by default with old MinGW versions). Private fonts are still made available to wxGraphicsContext as well by providing access to them from GDI+ code via wxGetPrivateFontFileNames(). --- src/msw/font.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++ src/msw/graphics.cpp | 38 ++++++----------------------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/msw/font.cpp b/src/msw/font.cpp index a5243d1181..6116920108 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -34,6 +34,7 @@ #endif // WX_PRECOMP #include "wx/encinfo.h" +#include "wx/filename.h" #include "wx/fontutil.h" #include "wx/fontmap.h" @@ -1083,3 +1084,49 @@ bool wxFont::IsFixedWidth() const // those meanings are the opposite of what the constant name implies." return !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); } + +// ---------------------------------------------------------------------------- +// Private fonts support +// ---------------------------------------------------------------------------- + +namespace +{ + +// Contains the file names of all fonts added by AddPrivateFont(). +wxArrayString gs_privateFontFileNames; + +} // anonymous namespace + +// Accessor for use in src/msw/graphics.cpp only. +extern const wxArrayString& wxGetPrivateFontFileNames() +{ + return gs_privateFontFileNames; +} + +bool wxFontBase::AddPrivateFont(const wxString& filename) +{ + if ( !wxFileName::FileExists(filename) ) + { + wxLogError(_("Font file \"%s\" doesn't exist."), filename); + return false; + } + + gs_privateFontFileNames.Add(filename); + return true; +} + +bool wxFontBase::ActivatePrivateFonts() +{ + const int n = gs_privateFontFileNames.size(); + for ( int i = 0 ; i < n; i++ ) + { + const wxString& fname = gs_privateFontFileNames[i]; + if ( !AddFontResourceEx(fname.t_str(), FR_PRIVATE, 0) ) + { + wxLogSysError(_("Font file \"%s\" couldn't be loaded"), + fname); + } + } + + return true; +} diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index fd5957e59a..ed4f4e05bf 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -37,7 +37,6 @@ #include "wx/dcprint.h" #endif -#include "wx/filename.h" #include "wx/stack.h" #include "wx/private/graphics.h" @@ -967,39 +966,13 @@ wxGDIPlusBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo, namespace { -wxArrayString gs_privateFontFileNames; Gdiplus::PrivateFontCollection* gs_privateFonts = NULL; Gdiplus::FontFamily* gs_pFontFamily = NULL; } // anonymous namespace -bool wxFontBase::AddPrivateFont(const wxString& filename) -{ - if ( !wxFileName::FileExists(filename) ) - { - wxLogError(_("Font file \"%s\" doesn't exist."), filename); - return false; - } - - gs_privateFontFileNames.Add(filename); - return true; -} - -bool wxFontBase::ActivatePrivateFonts() -{ - const int n = gs_privateFontFileNames.size(); - for ( int i = 0 ; i < n; i++ ) - { - const wxString& fname = gs_privateFontFileNames[i]; - if ( !AddFontResourceEx(fname.t_str(), FR_PRIVATE, 0) ) - { - wxLogSysError(_("Font file \"%s\" couldn't be loaded"), - fname); - } - } - - return true; -} +// This function is defined in src/msw/font.cpp. +extern const wxArrayString& wxGetPrivateFontFileNames(); //----------------------------------------------------------------------------- // wxGDIPlusFont implementation @@ -2343,13 +2316,14 @@ void wxGDIPlusRenderer::Load() m_loaded = 1; // Make private fonts available to GDI+, if any. - const int n = gs_privateFontFileNames.size(); + const wxArrayString& privateFonts = wxGetPrivateFontFileNames(); + const size_t n = privateFonts.size(); if ( n ) { gs_privateFonts = new Gdiplus::PrivateFontCollection(); - for ( int i = 0 ; i < n; i++ ) + for ( size_t i = 0 ; i < n; i++ ) { - const wxString& fname = gs_privateFontFileNames[i]; + const wxString& fname = privateFonts[i]; gs_privateFonts->AddFontFile(fname.t_str()); } From 28864d3ef6ee9196af3d5dde6573143b231cd820 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 18:05:07 +0100 Subject: [PATCH 05/17] Clean up private fonts on library shut down under MSW Ensure we don't keep the values in the global gs_privateFontFileNames variable if the library is shutdown and reinitialized later, this would be unexpected. --- src/msw/font.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/msw/font.cpp b/src/msw/font.cpp index 6116920108..ea6920cfff 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -30,6 +30,7 @@ #include "wx/utils.h" #include "wx/app.h" #include "wx/log.h" + #include "wx/module.h" #include "wx/msw/private.h" #endif // WX_PRECOMP @@ -1103,6 +1104,22 @@ extern const wxArrayString& wxGetPrivateFontFileNames() return gs_privateFontFileNames; } +// We need to use a module to clean up the list of private fonts when the +// library is shut down. +class wxPrivateFontsListModule : public wxModule +{ +public: + wxPrivateFontsListModule() { } + + bool OnInit() wxOVERRIDE { return true; } + void OnExit() wxOVERRIDE { gs_privateFontFileNames.clear(); } + +private: + wxDECLARE_DYNAMIC_CLASS(wxPrivateFontsListModule); +}; + +wxIMPLEMENT_DYNAMIC_CLASS(wxPrivateFontsListModule, wxModule); + bool wxFontBase::AddPrivateFont(const wxString& filename) { if ( !wxFileName::FileExists(filename) ) From ac4f99fa0d5d71b3f9f4290b2bbd41135a2ccd47 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 18:23:11 +0100 Subject: [PATCH 06/17] Test for FontConfig availability in configure when using wxGTK This library is now needed in order to implement wxFont private font methods. --- configure | 85 +++++++++++++++++++++++++++++++++++++++++++ configure.in | 8 ++++ include/wx/gtk/font.h | 2 +- setup.h.in | 4 ++ setup.h_vms | 8 ++++ src/gtk/font.cpp | 8 ++-- 6 files changed, 109 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 80b1e5d3f4..db8cc436a3 100755 --- a/configure +++ b/configure @@ -978,6 +978,8 @@ X_CFLAGS XMKMF DIRECTFB_LIBS DIRECTFB_CFLAGS +FONTCONFIG_LIBS +FONTCONFIG_CFLAGS GTK_CONFIG GTK_LIBS GTK_CFLAGS @@ -1366,6 +1368,8 @@ CXX CXXFLAGS CCC PKG_CONFIG +FONTCONFIG_CFLAGS +FONTCONFIG_LIBS DIRECTFB_CFLAGS DIRECTFB_LIBS XMKMF @@ -2348,6 +2352,10 @@ Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags PKG_CONFIG path to pkg-config utility + FONTCONFIG_CFLAGS + C compiler flags for FONTCONFIG, overriding pkg-config + FONTCONFIG_LIBS + linker flags for FONTCONFIG, overriding pkg-config DIRECTFB_CFLAGS C compiler flags for DIRECTFB, overriding pkg-config DIRECTFB_LIBS @@ -22471,6 +22479,83 @@ $as_echo "not found" >&6; } fi fi + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FONTCONFIG" >&5 +$as_echo_n "checking for FONTCONFIG... " >&6; } + +if test -n "$PKG_CONFIG"; then + if test -n "$FONTCONFIG_CFLAGS"; then + pkg_cv_FONTCONFIG_CFLAGS="$FONTCONFIG_CFLAGS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig\""; } >&5 + ($PKG_CONFIG --exists --print-errors "fontconfig") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi +if test -n "$PKG_CONFIG"; then + if test -n "$FONTCONFIG_LIBS"; then + pkg_cv_FONTCONFIG_LIBS="$FONTCONFIG_LIBS" + else + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig\""; } >&5 + ($PKG_CONFIG --exists --print-errors "fontconfig") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig" 2>/dev/null` +else + pkg_failed=yes +fi + fi +else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "fontconfig"` + else + FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig"` + fi + # Put the nasty error message in config.log where it belongs + echo "$FONTCONFIG_PKG_ERRORS" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&5 +$as_echo "$as_me: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&2;} +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&5 +$as_echo "$as_me: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&2;} +else + FONTCONFIG_CFLAGS=$pkg_cv_FONTCONFIG_CFLAGS + FONTCONFIG_LIBS=$pkg_cv_FONTCONFIG_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + $as_echo "#define wxUSE_FONTCONFIG 1" >>confdefs.h + + CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" + GUI_TK_LIBRARY="$GUI_TK_LIBRARY $FONTCONFIG_LIBS" + +fi fi if test "$wxUSE_DFB" = 1; then diff --git a/configure.in b/configure.in index 5b65a0bc24..40ce665b4d 100644 --- a/configure.in +++ b/configure.in @@ -2962,6 +2962,14 @@ libraries returned by 'pkg-config gtk+-2.0 --libs' or 'gtk-config dnl AC_MSG_RESULT(not found) dnl fi fi + + PKG_CHECK_MODULES(FONTCONFIG, [fontconfig], + [ + AC_DEFINE(wxUSE_FONTCONFIG) + CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" + GUI_TK_LIBRARY="$GUI_TK_LIBRARY $FONTCONFIG_LIBS" + ], + [AC_MSG_WARN([fontconfig library not found, run-time font loading won't be supported by wxFont])]) fi if test "$wxUSE_DFB" = 1; then diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h index 669055c2c3..4bd38738d6 100644 --- a/include/wx/gtk/font.h +++ b/include/wx/gtk/font.h @@ -118,7 +118,7 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; -#ifndef __WXMSW__ +#if wxUSE_FONTCONFIG #define wxHAS_PRIVATE_FONTS 1 #endif diff --git a/setup.h.in b/setup.h.in index 0715a696e1..0d35c88436 100644 --- a/setup.h.in +++ b/setup.h.in @@ -833,6 +833,10 @@ */ #define wxUSE_PLUGINS 0 +/* + * Use FontConfig library for private fonts support in wxFont. + */ +#define wxUSE_FONTCONFIG 0 /* * Use GTK print for printing under GTK+ 2.10+ */ diff --git a/setup.h_vms b/setup.h_vms index d1f7842057..24e8301f4a 100644 --- a/setup.h_vms +++ b/setup.h_vms @@ -902,6 +902,14 @@ typedef pid_t GPid; * Use SDL for audio (Unix) */ #define wxUSE_LIBSDL 0 +/* + * Use FontConfig library for private fonts support in wxFont. + */ +#ifdef VMS_GTK2 +#define wxUSE_FONTCONFIG 1 +#else +#define wxUSE_FONTCONFIG 0 +#endif /* * Use GTK print for printing under GTK+ 2.10+ */ diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 297c567e25..8903aef9a8 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -20,6 +20,7 @@ #include "wx/font.h" #ifndef WX_PRECOMP + #include "wx/intl.h" #include "wx/log.h" #include "wx/utils.h" #include "wx/settings.h" @@ -31,11 +32,6 @@ #include "wx/gtk/private.h" -#ifdef GDK_WINDOWING_X11 - #include - #include -#endif - // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -564,6 +560,8 @@ bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const #ifdef wxHAS_PRIVATE_FONTS +#include + namespace { FcConfig* gs_fcConfig = NULL; From 4f5f4af3b1246cdd66bcc11ce88ca63b0e2db9f9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2017 21:00:13 +0100 Subject: [PATCH 07/17] Compilation fixes for wxUSE_STL==1 build Add an explicit call to wc_str() in one place where conversion to wchar_t* is needed and use wxString::operator==() instead of lstrcmp() to avoid having to perform this conversion explicitly in another place. --- src/msw/graphics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index ed4f4e05bf..003eefd41e 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -1000,7 +1000,7 @@ wxGDIPlusFontData::Init(const wxString& name, { wchar_t familyName[LF_FACESIZE]; int rc = gs_pFontFamily[j].GetFamilyName(familyName); - if ( rc == 0 && lstrcmp(name, familyName) == 0 ) + if ( rc == 0 && name == familyName ) { m_font = new Font(&gs_pFontFamily[j], size, style, fontUnit); break; @@ -1009,7 +1009,7 @@ wxGDIPlusFontData::Init(const wxString& name, } if ( !m_font ) - m_font = new Font(name, size, style, fontUnit); + m_font = new Font(name.wc_str(), size, style, fontUnit); m_textBrush = new SolidBrush(wxColourToColor(col)); } From 5d134711a14d0b7391ec6d8742ce52840d071179 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 15:22:27 +0100 Subject: [PATCH 08/17] Add BUNDLE_FONT_RESOURCES and use it in font sample Allow copying font files to the Fonts subdirectory of the app bundle, private fonts can only be loaded from there under macOS currently. --- build/bakefiles/mac_bundles.bkl | 12 ++++++++++++ samples/font/Makefile.in | 6 ++++-- samples/font/font.bkl | 2 ++ samples/font/makefile.bcc | 2 +- samples/font/makefile.gcc | 2 +- samples/font/makefile.vc | 2 +- samples/help/Makefile.in | 2 +- 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/build/bakefiles/mac_bundles.bkl b/build/bakefiles/mac_bundles.bkl index bb8a4b97f7..81ff638346 100644 --- a/build/bakefiles/mac_bundles.bkl +++ b/build/bakefiles/mac_bundles.bkl @@ -21,6 +21,7 @@ $(TOP_SRCDIR)src/osx/carbon/wxmac.icns + @@ -44,6 +45,7 @@ $(BUNDLE_PLIST) $(BUNDLE_ICON) $(BUNDLE_RESOURCES) + $(BUNDLE_FONT_RESOURCES) @@ -72,6 +74,16 @@ cp -f $(BUNDLE_RESOURCES) $(BUNDLE)/Resources + + + + mkdir -p $(BUNDLE)/Resources/Fonts + cp -f $(BUNDLE_FONT_RESOURCES) $(BUNDLE)/Resources/Fonts + + diff --git a/samples/font/Makefile.in b/samples/font/Makefile.in index 3291284be0..ea30d90e4d 100644 --- a/samples/font/Makefile.in +++ b/samples/font/Makefile.in @@ -149,7 +149,7 @@ font$(EXEEXT): $(FONT_OBJECTS) $(__font___win32rc) $(CXX) -o $@ $(FONT_OBJECTS) -L$(LIBDIRNAME) $(LDFLAGS_GUI) $(SAMPLES_RPATH_FLAG) $(LDFLAGS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) $(EXTRALIBS_FOR_GUI) $(__LIB_ZLIB_p) $(__LIB_REGEX_p) $(__LIB_EXPAT_p) $(EXTRALIBS_FOR_BASE) $(LIBS) $(__font___os2_emxbindcmd) -@COND_PLATFORM_MACOSX_1@font.app/Contents/PkgInfo: font$(EXEEXT) $(top_srcdir)/src/osx/carbon/Info.plist.in $(top_srcdir)/src/osx/carbon/wxmac.icns +@COND_PLATFORM_MACOSX_1@font.app/Contents/PkgInfo: font$(EXEEXT) $(top_srcdir)/src/osx/carbon/Info.plist.in $(top_srcdir)/src/osx/carbon/wxmac.icns $(srcdir)/wxprivate.ttf @COND_PLATFORM_MACOSX_1@ mkdir -p font.app/Contents @COND_PLATFORM_MACOSX_1@ mkdir -p font.app/Contents/MacOS @COND_PLATFORM_MACOSX_1@ mkdir -p font.app/Contents/Resources @@ -168,10 +168,12 @@ font$(EXEEXT): $(FONT_OBJECTS) $(__font___win32rc) @COND_PLATFORM_MACOSX_1@ @COND_PLATFORM_MACOSX_1@ @COND_PLATFORM_MACOSX_1@ cp -f $(top_srcdir)/src/osx/carbon/wxmac.icns font.app/Contents/Resources/wxmac.icns +@COND_PLATFORM_MACOSX_1@ mkdir -p font.app/Contents/Resources/Fonts +@COND_PLATFORM_MACOSX_1@ cp -f $(srcdir)/wxprivate.ttf font.app/Contents/Resources/Fonts @COND_PLATFORM_MACOSX_1@font_bundle: $(____font_BUNDLE_TGT_REF_DEP) -data: +data: @mkdir -p . @for f in wxprivate.ttf; do \ if test ! -f ./$$f -a ! -d ./$$f ; \ diff --git a/samples/font/font.bkl b/samples/font/font.bkl index bfa8333cb2..2eba3ad77f 100644 --- a/samples/font/font.bkl +++ b/samples/font/font.bkl @@ -1,6 +1,8 @@ + $(SRCDIR)/wxprivate.ttf + diff --git a/samples/font/makefile.bcc b/samples/font/makefile.bcc index 65f9a92a1f..7d8249c264 100644 --- a/samples/font/makefile.bcc +++ b/samples/font/makefile.bcc @@ -231,7 +231,7 @@ $(OBJS)\font.exe: $(FONT_OBJECTS) $(OBJS)\font_sample.res c0w32.obj $(FONT_OBJECTS),$@,, $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) ole2w32.lib oleacc.lib import32.lib cw32$(__THREADSFLAG_5)$(__RUNTIME_LIBS_8).lib,, $(OBJS)\font_sample.res | -data: +data: if not exist $(OBJS) mkdir $(OBJS) for %f in (wxprivate.ttf) do if not exist $(OBJS)\%f copy .\%f $(OBJS) diff --git a/samples/font/makefile.gcc b/samples/font/makefile.gcc index 47f208ff18..db2b679db0 100644 --- a/samples/font/makefile.gcc +++ b/samples/font/makefile.gcc @@ -220,7 +220,7 @@ clean: $(OBJS)\font.exe: $(FONT_OBJECTS) $(OBJS)\font_sample_rc.o $(CXX) -o $@ $(FONT_OBJECTS) $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lwsock32 -lwininet -loleacc -data: +data: if not exist $(OBJS) mkdir $(OBJS) for %%f in (wxprivate.ttf) do if not exist $(OBJS)\%%f copy .\%%f $(OBJS) diff --git a/samples/font/makefile.vc b/samples/font/makefile.vc index 431edcac5a..b5b0fb49ce 100644 --- a/samples/font/makefile.vc +++ b/samples/font/makefile.vc @@ -354,7 +354,7 @@ $(OBJS)\font.exe: $(FONT_OBJECTS) $(OBJS)\font_sample.res $(FONT_OBJECTS) $(FONT_RESOURCES) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregex$(WXUNICODEFLAG)$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib wsock32.lib wininet.lib << -data: +data: if not exist $(OBJS) mkdir $(OBJS) for %f in (wxprivate.ttf) do if not exist $(OBJS)\%f copy .\%f $(OBJS) diff --git a/samples/help/Makefile.in b/samples/help/Makefile.in index 824b37039b..baca165290 100644 --- a/samples/help/Makefile.in +++ b/samples/help/Makefile.in @@ -194,7 +194,7 @@ data: data_doc: @mkdir -p ./doc - @for f in aindex.html down.gif dxxgifs.tex HIER.html icon1.gif icon2.gif index.html logo.gif wx204.htm wx34.htm wxExtHelpController.html wxhelp.map wx.htm; do \ + @for f in aindex.html ClassGraph.class ClassGraphPanel.class ClassLayout.class down.gif dxxgifs.tex HIER.html HIERjava.html icon1.gif icon2.gif index.html logo.gif NavigatorButton.class USE_HELP.html wx204.htm wx34.htm wxExtHelpController.html wxhelp.map wx.htm; do \ if test ! -f ./doc/$$f -a ! -d ./doc/$$f ; \ then x=yep ; \ else x=`find $(srcdir)/doc/$$f -newer ./doc/$$f -print` ; \ From 5c17c4b74564eae51da74b81ff6731f3a431ce15 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 15:23:44 +0100 Subject: [PATCH 09/17] Set ATSApplicationFontsPath in Mac app bundle This is required to allow loading private fonts from the bundle Resources/Fonts subdirectory and doesn't seem to have any negative consequences for the applications which don't need this functionality. --- src/osx/carbon/Info.plist.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osx/carbon/Info.plist.in b/src/osx/carbon/Info.plist.in index 6bf5f8c3fd..7007f6d8c0 100644 --- a/src/osx/carbon/Info.plist.in +++ b/src/osx/carbon/Info.plist.in @@ -41,5 +41,7 @@ CSResourcesFileMapped + ATSApplicationFontsPath + Fonts From 5a13e4eda27f100e4714c08ae030886e1c71317d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 21:09:48 +0100 Subject: [PATCH 10/17] Clear wxFontEnumerator face names cache on library shutdown Don't rely on it being done during statics cleanup as this doesn't work if the library is shutdown and re-initialized. Use a module to do the cleanup, just as it's already done for a lot of other global data in wx. --- src/common/fontenumcmn.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/common/fontenumcmn.cpp b/src/common/fontenumcmn.cpp index d0df597226..a1a1bbf771 100644 --- a/src/common/fontenumcmn.cpp +++ b/src/common/fontenumcmn.cpp @@ -26,6 +26,31 @@ #if wxUSE_FONTENUM #include "wx/fontenum.h" +#include "wx/module.h" + +namespace +{ + +// Cached result of GetFacenames(). +wxArrayString gs_allFacenames; + +// Module used to ensure the cache is cleared on library shutdown and so is not +// reused if it re-initialized again later. +class wxFontEnumCacheCleanupModule : public wxModule +{ +public: + wxFontEnumCacheCleanupModule() { } + + bool OnInit() wxOVERRIDE { return true; } + void OnExit() wxOVERRIDE { gs_allFacenames.clear(); } + +private: + wxDECLARE_DYNAMIC_CLASS(wxFontEnumCacheCleanupModule); +}; + +wxIMPLEMENT_DYNAMIC_CLASS(wxFontEnumCacheCleanupModule, wxModule); + +} // anonymous namespace // ============================================================================ // implementation @@ -79,7 +104,8 @@ bool wxFontEnumerator::IsValidFacename(const wxString &facename) { // we cache the result of wxFontEnumerator::GetFacenames supposing that // the array of face names won't change in the session of this program - static wxArrayString s_arr = wxFontEnumerator::GetFacenames(); + if ( gs_allFacenames.empty() ) + gs_allFacenames = wxFontEnumerator::GetFacenames(); #ifdef __WXMSW__ // Quoting the MSDN: @@ -95,7 +121,7 @@ bool wxFontEnumerator::IsValidFacename(const wxString &facename) #endif // is given font face name a valid one ? - if (s_arr.Index(facename, false) == wxNOT_FOUND) + if (gs_allFacenames.Index(facename, false) == wxNOT_FOUND) return false; return true; From ed655bfcde61f6d0c2e2eb9d4967a2889e76c730 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 21:13:20 +0100 Subject: [PATCH 11/17] Add wxFontEnumerator::InvalidateCache() This is necessary to recognize new fonts, for example those added using AddPrivateFont(), as being valid: otherwise they were not found in the cache and couldn't be used in wxGTK. --- include/wx/fontenum.h | 5 +++++ interface/wx/fontenum.h | 11 +++++++++++ src/common/fontenumcmn.cpp | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/include/wx/fontenum.h b/include/wx/fontenum.h index 782dc7fd9e..fcdb31f9c1 100644 --- a/include/wx/fontenum.h +++ b/include/wx/fontenum.h @@ -74,6 +74,11 @@ public: // in the user's system static bool IsValidFacename(const wxString &str); + // Invalidate cache used by some of the methods of this class internally. + // This should be called if the list of the fonts available on the system + // changes, for whatever reason. + static void InvalidateCache(); + private: #ifdef wxHAS_UTF8_FONTS // helper for ports that only use UTF-8 encoding natively diff --git a/interface/wx/fontenum.h b/interface/wx/fontenum.h index ba5cfa8cf2..c0da82258f 100644 --- a/interface/wx/fontenum.h +++ b/interface/wx/fontenum.h @@ -73,6 +73,17 @@ public: */ static bool IsValidFacename(const wxString& facename); + /** + Invalidate cache used by some of the methods of this class internally. + + This method should be called if the list of the fonts available on the + system changes, for whatever reason. In particular, it is called + automatically by wxFont::AddPrivateFont(). + + @since 3.1.1 + */ + static void InvalidateCache(); + /** Called by EnumerateFacenames() for each match. diff --git a/src/common/fontenumcmn.cpp b/src/common/fontenumcmn.cpp index a1a1bbf771..183e241287 100644 --- a/src/common/fontenumcmn.cpp +++ b/src/common/fontenumcmn.cpp @@ -127,6 +127,12 @@ bool wxFontEnumerator::IsValidFacename(const wxString &facename) return true; } +/* static */ +void wxFontEnumerator::InvalidateCache() +{ + gs_allFacenames.clear(); +} + #ifdef wxHAS_UTF8_FONTS bool wxFontEnumerator::EnumerateEncodingsUTF8(const wxString& facename) { From 3158a46ce75873fd3931c23f79e874f19afdc126 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 21:29:38 +0100 Subject: [PATCH 12/17] Require fontconfig >= 2.8 and change its guard macro name FcConfigAppFontAddFile() that we use is only available since 2.8, so check for at least this version of the library in configure. Also change the macro guarding its use to the more semantically appropriate "wxHAVE" rather than "wxUSE" and make it more precise by adding "2_8_0" suffix to it. --- configure | 2 +- configure.in | 6 +++--- include/wx/gtk/font.h | 2 +- setup.h.in | 2 +- setup.h_vms | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/configure b/configure index db8cc436a3..19e4e73eb6 100755 --- a/configure +++ b/configure @@ -22550,7 +22550,7 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - $as_echo "#define wxUSE_FONTCONFIG 1" >>confdefs.h + $as_echo "#define wxHAVE_FONTCONFIG_2_8_0 1" >>confdefs.h CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" GUI_TK_LIBRARY="$GUI_TK_LIBRARY $FONTCONFIG_LIBS" diff --git a/configure.in b/configure.in index 40ce665b4d..77b79235c1 100644 --- a/configure.in +++ b/configure.in @@ -2963,13 +2963,13 @@ libraries returned by 'pkg-config gtk+-2.0 --libs' or 'gtk-config dnl fi fi - PKG_CHECK_MODULES(FONTCONFIG, [fontconfig], + PKG_CHECK_MODULES(FONTCONFIG, [fontconfig >= 2.8.0], [ - AC_DEFINE(wxUSE_FONTCONFIG) + AC_DEFINE(wxHAVE_FONTCONFIG_2_8_0) CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" GUI_TK_LIBRARY="$GUI_TK_LIBRARY $FONTCONFIG_LIBS" ], - [AC_MSG_WARN([fontconfig library not found, run-time font loading won't be supported by wxFont])]) + [AC_MSG_WARN([fontconfig library not found or too old, run-time font loading won't be supported by wxFont])]) fi if test "$wxUSE_DFB" = 1; then diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h index 4bd38738d6..a8f8ce381f 100644 --- a/include/wx/gtk/font.h +++ b/include/wx/gtk/font.h @@ -118,7 +118,7 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; -#if wxUSE_FONTCONFIG +#ifdef wxHAVE_FONTCONFIG_2_8_0 #define wxHAS_PRIVATE_FONTS 1 #endif diff --git a/setup.h.in b/setup.h.in index 0d35c88436..e173a50227 100644 --- a/setup.h.in +++ b/setup.h.in @@ -836,7 +836,7 @@ /* * Use FontConfig library for private fonts support in wxFont. */ -#define wxUSE_FONTCONFIG 0 +#undef wxHAVE_FONTCONFIG_2_8_0 /* * Use GTK print for printing under GTK+ 2.10+ */ diff --git a/setup.h_vms b/setup.h_vms index 24e8301f4a..e9958e410d 100644 --- a/setup.h_vms +++ b/setup.h_vms @@ -906,9 +906,9 @@ typedef pid_t GPid; * Use FontConfig library for private fonts support in wxFont. */ #ifdef VMS_GTK2 -#define wxUSE_FONTCONFIG 1 +#define wxHAVE_FONTCONFIG_2_8_0 1 #else -#define wxUSE_FONTCONFIG 0 +#undef wxHAVE_FONTCONFIG_2_8_0 #endif /* * Use GTK print for printing under GTK+ 2.10+ From d99a255e98aaaa898e8aacf0ca64843788c230dc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 21:40:52 +0100 Subject: [PATCH 13/17] Fix private fonts support in wxGTK Use pango_fc_font_map_set_config() to associate the FcConfig containing the private fonts with the global Pango context to make them available. Also use FcInitLoadConfigAndFonts() instead of just FcConfigCreate() to initialize the new config with all the default fonts instead of just using our private fonts in it. --- src/gtk/font.cpp | 50 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 8903aef9a8..5d58852125 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -560,7 +560,14 @@ bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const #ifdef wxHAS_PRIVATE_FONTS +#include "wx/fontenum.h" +#include "wx/gtk/private.h" +#include "wx/gtk/private/object.h" + #include +#include + +extern PangoContext* wxGetPangoContext(); namespace { @@ -571,17 +578,11 @@ bool wxFontBase::AddPrivateFont(const wxString& filename) { if ( !gs_fcConfig ) { - gs_fcConfig = FcConfigGetCurrent(); + gs_fcConfig = FcInitLoadConfigAndFonts(); if ( !gs_fcConfig ) { - gs_fcConfig = FcConfigCreate(); - if ( !gs_fcConfig ) - { - wxLogError(_("Failed to add custom font \"%s\" as " - "font configuration object creation failed."), - filename); - return false; - } + wxLogError(_("Failed to create font configuration object.")); + return false; } } @@ -599,13 +600,38 @@ bool wxFontBase::AddPrivateFont(const wxString& filename) bool wxFontBase::ActivatePrivateFonts() { - if ( !FcConfigSetCurrent(gs_fcConfig) ) + wxGtkObject context(wxGetPangoContext()); + PangoFontMap* const fmap = pango_context_get_font_map(context); + if ( !fmap || !PANGO_IS_FC_FONT_MAP(fmap) ) { - wxLogError(_("Failed to update current font configuration.")); + wxLogError(_("Failed to register font configuration using private fonts.")); return false; } - return true; + wxString why; +#if PANGO_VERSION_CHECK(1,38,0) + if ( wx_pango_version_check(1,38,0) == NULL ) + { + PangoFcFontMap* const fcfmap = PANGO_FC_FONT_MAP(fmap); + pango_fc_font_map_set_config(fcfmap, gs_fcConfig); + + // Ensure that the face names defined by private fonts are recognized by + // our SetFaceName() which uses wxFontEnumerator to check if the name is in + // the list of available faces. + wxFontEnumerator::InvalidateCache(); + + return true; + } + else + { + why = _("system Pango library is too old, 1.38 or later required"); + } +#else // Pango < 1.38 + why = _("this application was compiled with too old Pango library version"); +#endif // Pango 1.38+/1.38- + + wxLogError(_("Using private fonts is not supported: %s."), why); + return false; } #endif // wxHAS_PRIVATE_FONTS From c9d1f9a71948af7cd028d9ef499cb13e9d9b8f0d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 21:44:34 +0100 Subject: [PATCH 14/17] Clean up FcConfig object on library shutdown Don't just leak it as was done before. --- src/gtk/font.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 5d58852125..2887537728 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -561,6 +561,7 @@ bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const #ifdef wxHAS_PRIVATE_FONTS #include "wx/fontenum.h" +#include "wx/module.h" #include "wx/gtk/private.h" #include "wx/gtk/private/object.h" @@ -571,8 +572,32 @@ extern PangoContext* wxGetPangoContext(); namespace { - FcConfig* gs_fcConfig = NULL; -} + +FcConfig* gs_fcConfig = NULL; + +// Module used to clean up the global FcConfig. +class wxFcConfigDestroyModule : public wxModule +{ +public: + wxFcConfigDestroyModule() { } + + bool OnInit() wxOVERRIDE { return true; } + void OnExit() wxOVERRIDE + { + if ( gs_fcConfig ) + { + FcConfigDestroy(gs_fcConfig); + gs_fcConfig = NULL; + } + } + +private: + wxDECLARE_DYNAMIC_CLASS(wxFcConfigDestroyModule); +}; + +wxIMPLEMENT_DYNAMIC_CLASS(wxFcConfigDestroyModule, wxModule); + +} // anonymous namespace bool wxFontBase::AddPrivateFont(const wxString& filename) { From 283f5a4d5678f7f936144b8dc365904e53704b60 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 13 Nov 2017 22:09:15 +0100 Subject: [PATCH 15/17] Remove useless wxFont::ActivatePrivateFonts() Just "activate" the font immediately when adding it using AddPrivateFont(), nothing seems to be gained from having two functions and it just makes things more complicated both when implementing and when using the API. --- docs/doxygen/overviews/font.h | 11 +++--- include/wx/font.h | 9 ++--- interface/wx/font.h | 25 ++++++-------- samples/font/font.cpp | 4 --- src/common/fontcmn.cpp | 5 --- src/gtk/font.cpp | 63 +++++++++++++++++------------------ src/msw/font.cpp | 22 ++---------- src/osx/fontutil.cpp | 6 ---- 8 files changed, 53 insertions(+), 92 deletions(-) diff --git a/docs/doxygen/overviews/font.h b/docs/doxygen/overviews/font.h index 49635f37ec..76103fdfa4 100644 --- a/docs/doxygen/overviews/font.h +++ b/docs/doxygen/overviews/font.h @@ -82,12 +82,9 @@ system. On Macintosh/OSX this can be arranged by placing the desired fonts within the Application Bundle in Contents/Resources/Fonts and using the ATSApplicationFontsPath key to point there. The full details of the procedure there can be found as OSX developer resources. For the GTK+ and -Windows ports it is possible to add TrueType fonts at run-time using -a sequence of calls to wxFont::AddPrivateFont() to give the names of files -containing font data, followed by a call to wxFont::ActivatePrivateFonts() -to complete the process of making the fonts available. These functions -return false if they fail. They should be called just once before any -graphics contexts have been created or other activity liable to use fonts -has happened. +Windows ports it is possible to add TrueType fonts from arbitrary locations at +run-time using wxFont::AddPrivateFont(). Notice that under MSW this function +should be called before creating the first wxGraphicsContext object if you want +the private font to be usable from it. */ diff --git a/include/wx/font.h b/include/wx/font.h index f3731179f8..8236558201 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -328,11 +328,12 @@ public: // from the string representation of wxNativeFontInfo static wxFont *New(const wxString& strNativeFontDesc); - // These functions can be used to load private fonts if supported by this - // platform (wxHAS_PRIVATE_FONTS is defined): first add one or more files - // and then activate all of them at once. + // Load the font from the given file and return true on success or false on + // error (an error message will be logged in this case, unless there is no + // support for private fonts at all in the current port, in which case + // wxHAS_PRIVATE_FONTS will not be defined allowing to check for this at + // compile-time). static bool AddPrivateFont(const wxString& filename); - static bool ActivatePrivateFonts(); // comparison bool operator==(const wxFont& font) const; diff --git a/interface/wx/font.h b/interface/wx/font.h index 7bc5c14cec..9f7c37708f 100644 --- a/interface/wx/font.h +++ b/interface/wx/font.h @@ -678,30 +678,25 @@ public: @c ATSApplicationFontsPath to @c Fonts value in your @c Info.plist file. See also wxStandardPaths::GetResourcesDir(). - Notice that this method must be called before any graphics contexts - have been created. + Under MSW this method must be called before any wxGraphicsContext + objects have been created, otherwise the private font won't be usable + from them. + + Under Unix this method requires Pango 1.38 or later and will return @a + false and log an error message explaining the problem if this + requirement is not satisfied either at compile- or run-time. Currently this method is implemented for all major platforms but you may also test for @c wxHAS_PRIVATE_FONTS preprocessor symbol: if it is - not defined, this function and ActivatePrivatefonts() are not - implemented at all and always simply return false. + not defined, this function is not implemented at all and simply always + returns false. - @return @true if the font was added and ActivatePrivatefonts() should - be called next or @false if adding it failed. + @return @true if the font was added and can now be used. @since 3.1.1 */ static bool AddPrivateFont(const wxString& filename); - /** - Make all fonts registered by AddPrivateFont() actually available. - - @return @true if the private fonts can now be used or @false on error. - - @since 3.1.1 - */ - static bool ActivatePrivatefonts(); - /** Gets the point size. diff --git a/samples/font/font.cpp b/samples/font/font.cpp index baa7f0b054..6b5110064f 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -426,10 +426,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) { wxLogWarning("Failed to add private font from \"%s\"", privfont); } - else if ( !wxFont::ActivatePrivateFonts() ) - { - wxLogWarning("Failed to activate the private fonts"); - } else { menuSelect->AppendSeparator(); diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index f17d045167..dcb899a9ae 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -1148,9 +1148,4 @@ bool wxFontBase::AddPrivateFont(const wxString& WXUNUSED(filename)) return false; } -bool wxFontBase::ActivatePrivateFonts() -{ - return false; -} - #endif // !wxHAS_PRIVATE_FONTS diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 2887537728..f45680a1b3 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -601,42 +601,41 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxFcConfigDestroyModule, wxModule); bool wxFontBase::AddPrivateFont(const wxString& filename) { - if ( !gs_fcConfig ) - { - gs_fcConfig = FcInitLoadConfigAndFonts(); - if ( !gs_fcConfig ) - { - wxLogError(_("Failed to create font configuration object.")); - return false; - } - } - - if ( !FcConfigAppFontAddFile(gs_fcConfig, - reinterpret_cast( - static_cast(filename.utf8_str()) - )) ) - { - wxLogError(_("Failed to add custom font \"%s\"."), filename); - return false; - } - - return true; -} - -bool wxFontBase::ActivatePrivateFonts() -{ - wxGtkObject context(wxGetPangoContext()); - PangoFontMap* const fmap = pango_context_get_font_map(context); - if ( !fmap || !PANGO_IS_FC_FONT_MAP(fmap) ) - { - wxLogError(_("Failed to register font configuration using private fonts.")); - return false; - } - wxString why; + + // All this code only works if we have pango_context_get_font_map() which + // is new in 1.38, so don't bother compiling -- or running -- it if this is + // not the case. #if PANGO_VERSION_CHECK(1,38,0) if ( wx_pango_version_check(1,38,0) == NULL ) { + if ( !gs_fcConfig ) + { + gs_fcConfig = FcInitLoadConfigAndFonts(); + if ( !gs_fcConfig ) + { + wxLogError(_("Failed to create font configuration object.")); + return false; + } + } + + if ( !FcConfigAppFontAddFile(gs_fcConfig, + reinterpret_cast( + static_cast(filename.utf8_str()) + )) ) + { + wxLogError(_("Failed to add custom font \"%s\"."), filename); + return false; + } + + wxGtkObject context(wxGetPangoContext()); + PangoFontMap* const fmap = pango_context_get_font_map(context); + if ( !fmap || !PANGO_IS_FC_FONT_MAP(fmap) ) + { + wxLogError(_("Failed to register font configuration using private fonts.")); + return false; + } + PangoFcFontMap* const fcfmap = PANGO_FC_FONT_MAP(fmap); pango_fc_font_map_set_config(fcfmap, gs_fcConfig); diff --git a/src/msw/font.cpp b/src/msw/font.cpp index ea6920cfff..4ef7642035 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -35,7 +35,6 @@ #endif // WX_PRECOMP #include "wx/encinfo.h" -#include "wx/filename.h" #include "wx/fontutil.h" #include "wx/fontmap.h" @@ -1122,28 +1121,13 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxPrivateFontsListModule, wxModule); bool wxFontBase::AddPrivateFont(const wxString& filename) { - if ( !wxFileName::FileExists(filename) ) + if ( !AddFontResourceEx(filename.t_str(), FR_PRIVATE, 0) ) { - wxLogError(_("Font file \"%s\" doesn't exist."), filename); + wxLogSysError(_("Font file \"%s\" couldn't be loaded"), filename); return false; } + // Remember it for use in wxGDIPlusRenderer::Load(). gs_privateFontFileNames.Add(filename); return true; } - -bool wxFontBase::ActivatePrivateFonts() -{ - const int n = gs_privateFontFileNames.size(); - for ( int i = 0 ; i < n; i++ ) - { - const wxString& fname = gs_privateFontFileNames[i]; - if ( !AddFontResourceEx(fname.t_str(), FR_PRIVATE, 0) ) - { - wxLogSysError(_("Font file \"%s\" couldn't be loaded"), - fname); - } - } - - return true; -} diff --git a/src/osx/fontutil.cpp b/src/osx/fontutil.cpp index dd67c6322f..5cf015bcda 100644 --- a/src/osx/fontutil.cpp +++ b/src/osx/fontutil.cpp @@ -95,12 +95,6 @@ bool wxFontBase::AddPrivateFont(const wxString& filename) return true; } -bool wxFontBase::ActivatePrivateFonts() -{ - // Nothing to do here. - return true; -} - // ---------------------------------------------------------------------------- // helper functions // ---------------------------------------------------------------------------- From a98c51e6bcc28c2f16c279229e97ff0674010ea2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Nov 2017 15:22:35 +0100 Subject: [PATCH 16/17] Check for pangoft2 >= 1.38 in configure too We need to use PKG_CHECK_MODULES(pangoft2) anyhow because we need to link with its libraries, so make the version check there too and simplify wxFont::AddPrivateFont() implementation in wxGTK. --- configure | 58 ++++++++++++++++----------------- configure.in | 2 +- src/gtk/font.cpp | 83 +++++++++++++++++++++--------------------------- 3 files changed, 67 insertions(+), 76 deletions(-) diff --git a/configure b/configure index 19e4e73eb6..ff0ab1a102 100755 --- a/configure +++ b/configure @@ -978,8 +978,8 @@ X_CFLAGS XMKMF DIRECTFB_LIBS DIRECTFB_CFLAGS -FONTCONFIG_LIBS -FONTCONFIG_CFLAGS +PRIVATE_FONTS_LIBS +PRIVATE_FONTS_CFLAGS GTK_CONFIG GTK_LIBS GTK_CFLAGS @@ -1368,8 +1368,8 @@ CXX CXXFLAGS CCC PKG_CONFIG -FONTCONFIG_CFLAGS -FONTCONFIG_LIBS +PRIVATE_FONTS_CFLAGS +PRIVATE_FONTS_LIBS DIRECTFB_CFLAGS DIRECTFB_LIBS XMKMF @@ -2352,10 +2352,10 @@ Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags PKG_CONFIG path to pkg-config utility - FONTCONFIG_CFLAGS - C compiler flags for FONTCONFIG, overriding pkg-config - FONTCONFIG_LIBS - linker flags for FONTCONFIG, overriding pkg-config + PRIVATE_FONTS_CFLAGS + C compiler flags for PRIVATE_FONTS, overriding pkg-config + PRIVATE_FONTS_LIBS + linker flags for PRIVATE_FONTS, overriding pkg-config DIRECTFB_CFLAGS C compiler flags for DIRECTFB, overriding pkg-config DIRECTFB_LIBS @@ -22482,20 +22482,20 @@ $as_echo "not found" >&6; } pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FONTCONFIG" >&5 -$as_echo_n "checking for FONTCONFIG... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PRIVATE_FONTS" >&5 +$as_echo_n "checking for PRIVATE_FONTS... " >&6; } if test -n "$PKG_CONFIG"; then - if test -n "$FONTCONFIG_CFLAGS"; then - pkg_cv_FONTCONFIG_CFLAGS="$FONTCONFIG_CFLAGS" + if test -n "$PRIVATE_FONTS_CFLAGS"; then + pkg_cv_PRIVATE_FONTS_CFLAGS="$PRIVATE_FONTS_CFLAGS" else if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig\""; } >&5 - ($PKG_CONFIG --exists --print-errors "fontconfig") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.8.0 pangoft2 >= 1.38.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.8.0 pangoft2 >= 1.38.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig" 2>/dev/null` + pkg_cv_PRIVATE_FONTS_CFLAGS=`$PKG_CONFIG --cflags "fontconfig >= 2.8.0 pangoft2 >= 1.38.0" 2>/dev/null` else pkg_failed=yes fi @@ -22504,16 +22504,16 @@ else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then - if test -n "$FONTCONFIG_LIBS"; then - pkg_cv_FONTCONFIG_LIBS="$FONTCONFIG_LIBS" + if test -n "$PRIVATE_FONTS_LIBS"; then + pkg_cv_PRIVATE_FONTS_LIBS="$PRIVATE_FONTS_LIBS" else if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig\""; } >&5 - ($PKG_CONFIG --exists --print-errors "fontconfig") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.8.0 pangoft2 >= 1.38.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.8.0 pangoft2 >= 1.38.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig" 2>/dev/null` + pkg_cv_PRIVATE_FONTS_LIBS=`$PKG_CONFIG --libs "fontconfig >= 2.8.0 pangoft2 >= 1.38.0" 2>/dev/null` else pkg_failed=yes fi @@ -22532,21 +22532,21 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "fontconfig"` + PRIVATE_FONTS_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "fontconfig >= 2.8.0 pangoft2 >= 1.38.0"` else - FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig"` + PRIVATE_FONTS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig >= 2.8.0 pangoft2 >= 1.38.0"` fi # Put the nasty error message in config.log where it belongs - echo "$FONTCONFIG_PKG_ERRORS" >&5 + echo "$PRIVATE_FONTS_PKG_ERRORS" >&5 - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&5 -$as_echo "$as_me: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&5 +$as_echo "$as_me: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&2;} elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&5 -$as_echo "$as_me: WARNING: fontconfig library not found, run-time font loading won't be supported by wxFont" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&5 +$as_echo "$as_me: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&2;} else - FONTCONFIG_CFLAGS=$pkg_cv_FONTCONFIG_CFLAGS - FONTCONFIG_LIBS=$pkg_cv_FONTCONFIG_LIBS + PRIVATE_FONTS_CFLAGS=$pkg_cv_PRIVATE_FONTS_CFLAGS + PRIVATE_FONTS_LIBS=$pkg_cv_PRIVATE_FONTS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } diff --git a/configure.in b/configure.in index 77b79235c1..47f7e55117 100644 --- a/configure.in +++ b/configure.in @@ -2963,7 +2963,7 @@ libraries returned by 'pkg-config gtk+-2.0 --libs' or 'gtk-config dnl fi fi - PKG_CHECK_MODULES(FONTCONFIG, [fontconfig >= 2.8.0], + PKG_CHECK_MODULES(PRIVATE_FONTS, [fontconfig >= 2.8.0 pangoft2 >= 1.38.0], [ AC_DEFINE(wxHAVE_FONTCONFIG_2_8_0) CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index f45680a1b3..b14f68b218 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -601,61 +601,52 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxFcConfigDestroyModule, wxModule); bool wxFontBase::AddPrivateFont(const wxString& filename) { - wxString why; - - // All this code only works if we have pango_context_get_font_map() which - // is new in 1.38, so don't bother compiling -- or running -- it if this is - // not the case. -#if PANGO_VERSION_CHECK(1,38,0) - if ( wx_pango_version_check(1,38,0) == NULL ) + // We already checked that we have the required functions at compile-time, + // but we should also check if they're available at run-time in case we use + // older versions of them than the ones we were compiled with. + if ( wx_pango_version_check(1,38,0) != NULL ) { + wxLogError(_("Using private fonts is not supported on this system: " + "Pango library is too old, 1.38 or later required.")); + return false; + } + + if ( !gs_fcConfig ) + { + gs_fcConfig = FcInitLoadConfigAndFonts(); if ( !gs_fcConfig ) { - gs_fcConfig = FcInitLoadConfigAndFonts(); - if ( !gs_fcConfig ) - { - wxLogError(_("Failed to create font configuration object.")); - return false; - } - } - - if ( !FcConfigAppFontAddFile(gs_fcConfig, - reinterpret_cast( - static_cast(filename.utf8_str()) - )) ) - { - wxLogError(_("Failed to add custom font \"%s\"."), filename); + wxLogError(_("Failed to create font configuration object.")); return false; } - - wxGtkObject context(wxGetPangoContext()); - PangoFontMap* const fmap = pango_context_get_font_map(context); - if ( !fmap || !PANGO_IS_FC_FONT_MAP(fmap) ) - { - wxLogError(_("Failed to register font configuration using private fonts.")); - return false; - } - - PangoFcFontMap* const fcfmap = PANGO_FC_FONT_MAP(fmap); - pango_fc_font_map_set_config(fcfmap, gs_fcConfig); - - // Ensure that the face names defined by private fonts are recognized by - // our SetFaceName() which uses wxFontEnumerator to check if the name is in - // the list of available faces. - wxFontEnumerator::InvalidateCache(); - - return true; } - else + + if ( !FcConfigAppFontAddFile(gs_fcConfig, + reinterpret_cast( + static_cast(filename.utf8_str()) + )) ) { - why = _("system Pango library is too old, 1.38 or later required"); + wxLogError(_("Failed to add custom font \"%s\"."), filename); + return false; } -#else // Pango < 1.38 - why = _("this application was compiled with too old Pango library version"); -#endif // Pango 1.38+/1.38- - wxLogError(_("Using private fonts is not supported: %s."), why); - return false; + wxGtkObject context(wxGetPangoContext()); + PangoFontMap* const fmap = pango_context_get_font_map(context); + if ( !fmap || !PANGO_IS_FC_FONT_MAP(fmap) ) + { + wxLogError(_("Failed to register font configuration using private fonts.")); + return false; + } + + PangoFcFontMap* const fcfmap = PANGO_FC_FONT_MAP(fmap); + pango_fc_font_map_set_config(fcfmap, gs_fcConfig); + + // Ensure that the face names defined by private fonts are recognized by + // our SetFaceName() which uses wxFontEnumerator to check if the name is in + // the list of available faces. + wxFontEnumerator::InvalidateCache(); + + return true; } #endif // wxHAS_PRIVATE_FONTS From b040dab0ca3be462230a4ce07d20250dc638e2c8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Nov 2017 15:24:15 +0100 Subject: [PATCH 17/17] Add wxUSE_PRIVATE_FONTS and drop wxHAS_PRIVATE_FONTS Handle this feature as all the other ones and provide a configure switch and a setup.h option to disable it if necessary, as it may be desirable to do it, especially under Linux, to avoid extra dependency on pangoft2 if this functionality is unnecessary. --- configure | 52 +++++++++++++++++++++---- configure.in | 21 ++++++---- docs/doxygen/mainpages/const_cpp.h | 1 - docs/doxygen/mainpages/const_wxusedef.h | 1 + include/wx/android/setup.h | 24 ++++++++---- include/wx/chkconf.h | 15 +++++++ include/wx/font.h | 7 ++-- include/wx/gtk/font.h | 4 -- include/wx/gtk/setup0.h | 24 ++++++++---- include/wx/motif/setup0.h | 24 ++++++++---- include/wx/msw/font.h | 2 - include/wx/msw/setup0.h | 24 ++++++++---- include/wx/osx/font.h | 2 - include/wx/osx/setup0.h | 10 +++++ include/wx/setup_inc.h | 10 +++++ include/wx/univ/setup0.h | 24 ++++++++---- interface/wx/font.h | 8 ++-- samples/font/font.cpp | 4 +- setup.h.in | 6 +-- setup.h_vms | 8 ---- src/common/fontcmn.cpp | 13 ------- src/gtk/font.cpp | 4 +- src/msw/font.cpp | 4 ++ src/msw/graphics.cpp | 12 ++++++ src/osx/fontutil.cpp | 4 ++ 25 files changed, 213 insertions(+), 95 deletions(-) diff --git a/configure b/configure index ff0ab1a102..b3b64b1826 100755 --- a/configure +++ b/configure @@ -1270,6 +1270,7 @@ enable_notifmsg enable_odcombobox enable_popupwin enable_prefseditor +enable_privatefonts enable_radiobox enable_radiobtn enable_richmsgdlg @@ -2209,6 +2210,7 @@ Optional Features: --enable-odcombobox use wxOwnerDrawnComboBox class --enable-popupwin use wxPopUpWindow class --enable-prefseditor use wxPreferencesEditor class + --enable-privatefonts provide wxFont::AddPrivateFont() method --enable-radiobox use wxRadioBox class --enable-radiobtn use wxRadioButton class --enable-richmsgdlg use wxRichMessageDialog class @@ -10192,6 +10194,35 @@ fi eval "$wx_cv_use_prefseditor" + enablestring= + defaultval=$wxUSE_ALL_FEATURES + if test -z "$defaultval"; then + if test x"$enablestring" = xdisable; then + defaultval=yes + else + defaultval=no + fi + fi + + # Check whether --enable-privatefonts was given. +if test "${enable_privatefonts+set}" = set; then : + enableval=$enable_privatefonts; + if test "$enableval" = yes; then + wx_cv_use_privatefonts='wxUSE_PRIVATE_FONTS=yes' + else + wx_cv_use_privatefonts='wxUSE_PRIVATE_FONTS=no' + fi + +else + + wx_cv_use_privatefonts='wxUSE_PRIVATE_FONTS=${'DEFAULT_wxUSE_PRIVATE_FONTS":-$defaultval}" + +fi + + + eval "$wx_cv_use_privatefonts" + + enablestring= defaultval=$wxUSE_ALL_FEATURES if test -z "$defaultval"; then @@ -22480,6 +22511,7 @@ $as_echo "not found" >&6; } fi + if test "$wxUSE_PRIVATE_FONTS" = "yes"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PRIVATE_FONTS" >&5 @@ -22539,23 +22571,24 @@ fi # Put the nasty error message in config.log where it belongs echo "$PRIVATE_FONTS_PKG_ERRORS" >&5 - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&5 -$as_echo "$as_me: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: run-time font loading won't be supported by wxFont" >&5 +$as_echo "$as_me: WARNING: run-time font loading won't be supported by wxFont" >&2;} elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&5 -$as_echo "$as_me: WARNING: fontconfig library not found or too old, run-time font loading won't be supported by wxFont" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: run-time font loading won't be supported by wxFont" >&5 +$as_echo "$as_me: WARNING: run-time font loading won't be supported by wxFont" >&2;} else PRIVATE_FONTS_CFLAGS=$pkg_cv_PRIVATE_FONTS_CFLAGS PRIVATE_FONTS_LIBS=$pkg_cv_PRIVATE_FONTS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - $as_echo "#define wxHAVE_FONTCONFIG_2_8_0 1" >>confdefs.h + $as_echo "#define wxUSE_PRIVATE_FONTS 1" >>confdefs.h - CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" - GUI_TK_LIBRARY="$GUI_TK_LIBRARY $FONTCONFIG_LIBS" + CXXFLAGS="$PRIVATE_FONTS_CFLAGS $CXXFLAGS" + GUI_TK_LIBRARY="$GUI_TK_LIBRARY $PRIVATE_FONTS_LIBS" fi + fi fi if test "$wxUSE_DFB" = 1; then @@ -34371,6 +34404,11 @@ if test "$wxUSE_PREFERENCES_EDITOR" = "yes"; then SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS preferences" fi +if test "$wxUSE_PRIVATE_FONTS" = "yes"; then + $as_echo "#define wxUSE_PRIVATE_FONTS 1" >>confdefs.h + +fi + if test "$wxUSE_DIALUP_MANAGER" = "yes"; then if test "$wxUSE_MAC" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Dialup manager not supported on this platform... disabled" >&5 diff --git a/configure.in b/configure.in index 47f7e55117..7d00d5d9ff 100644 --- a/configure.in +++ b/configure.in @@ -925,6 +925,7 @@ WX_ARG_FEATURE(notifmsg, [ --enable-notifmsg use wxNotificationMessage WX_ARG_FEATURE(odcombobox, [ --enable-odcombobox use wxOwnerDrawnComboBox class], wxUSE_ODCOMBOBOX) WX_ARG_FEATURE(popupwin, [ --enable-popupwin use wxPopUpWindow class], wxUSE_POPUPWIN) WX_ARG_FEATURE(prefseditor, [ --enable-prefseditor use wxPreferencesEditor class], wxUSE_PREFERENCES_EDITOR) +WX_ARG_FEATURE(privatefonts,[ --enable-privatefonts provide wxFont::AddPrivateFont() method], wxUSE_PRIVATE_FONTS) WX_ARG_FEATURE(radiobox, [ --enable-radiobox use wxRadioBox class], wxUSE_RADIOBOX) WX_ARG_FEATURE(radiobtn, [ --enable-radiobtn use wxRadioButton class], wxUSE_RADIOBTN) WX_ARG_FEATURE(richmsgdlg, [ --enable-richmsgdlg use wxRichMessageDialog class], wxUSE_RICHMSGDLG) @@ -2963,13 +2964,15 @@ libraries returned by 'pkg-config gtk+-2.0 --libs' or 'gtk-config dnl fi fi - PKG_CHECK_MODULES(PRIVATE_FONTS, [fontconfig >= 2.8.0 pangoft2 >= 1.38.0], - [ - AC_DEFINE(wxHAVE_FONTCONFIG_2_8_0) - CXXFLAGS="$FONTCONFIG_CFLAGS $CXXFLAGS" - GUI_TK_LIBRARY="$GUI_TK_LIBRARY $FONTCONFIG_LIBS" - ], - [AC_MSG_WARN([fontconfig library not found or too old, run-time font loading won't be supported by wxFont])]) + if test "$wxUSE_PRIVATE_FONTS" = "yes"; then + PKG_CHECK_MODULES(PRIVATE_FONTS, [fontconfig >= 2.8.0 pangoft2 >= 1.38.0], + [ + AC_DEFINE(wxUSE_PRIVATE_FONTS) + CXXFLAGS="$PRIVATE_FONTS_CFLAGS $CXXFLAGS" + GUI_TK_LIBRARY="$GUI_TK_LIBRARY $PRIVATE_FONTS_LIBS" + ], + [AC_MSG_WARN([run-time font loading won't be supported by wxFont])]) + fi fi if test "$wxUSE_DFB" = 1; then @@ -6904,6 +6907,10 @@ if test "$wxUSE_PREFERENCES_EDITOR" = "yes"; then SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS preferences" fi +if test "$wxUSE_PRIVATE_FONTS" = "yes"; then + AC_DEFINE(wxUSE_PRIVATE_FONTS) +fi + if test "$wxUSE_DIALUP_MANAGER" = "yes"; then if test "$wxUSE_MAC" = 1; then AC_MSG_WARN([Dialup manager not supported on this platform... disabled]) diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index 3fd074fb70..1756d18a82 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -188,7 +188,6 @@ Currently the following symbols exist: @itemdef{wxHAS_IMAGES_IN_RESOURCES, Defined if Windows resource files or OS/2 resource files are available on the current platform.} @itemdef{wxHAS_POWER_EVENTS, Defined if wxPowerEvent are ever generated on the current platform.} -@itemdef{wxHAS_PRIVATE_FONTS, Defined if wxFont::AddPrivateFont() is implemented.} @itemdef{wxHAS_RADIO_MENU_ITEMS, Defined if the current port supports radio menu items (see wxMenu::AppendRadioItem).} @itemdef{wxHAS_RAW_BITMAP, Defined if direct access to bitmap data using the classes in @c wx/rawbmp.h is supported.} diff --git a/docs/doxygen/mainpages/const_wxusedef.h b/docs/doxygen/mainpages/const_wxusedef.h index 259416c087..3753cab329 100644 --- a/docs/doxygen/mainpages/const_wxusedef.h +++ b/docs/doxygen/mainpages/const_wxusedef.h @@ -186,6 +186,7 @@ library: @itemdef{wxUSE_POSTSCRIPT, Use wxPostScriptPrinter class.} @itemdef{wxUSE_PRINTF_POS_PARAMS, Use wxVsnprintf which supports positional parameters.} @itemdef{wxUSE_PRINTING_ARCHITECTURE, Enable printer classes.} +@itemdef{wxUSE_PRIVATE_FONTS, Implement wxFont::AddPrivateFont() method.} @itemdef{wxUSE_PROGRESSDLG, Enables progress dialog classes.} @itemdef{wxUSE_PROPGRID, Use wxPropertyGrid library.} @itemdef{wxUSE_PROTOCOL, Use wxProtocol and derived classes.} diff --git a/include/wx/android/setup.h b/include/wx/android/setup.h index d125af0798..2a6aceabed 100644 --- a/include/wx/android/setup.h +++ b/include/wx/android/setup.h @@ -794,14 +794,14 @@ // notice that we can't use wxCHECK_VISUALC_VERSION() here as this file is // included from wx/platform.h before wxCHECK_VISUALC_VERSION() is defined #ifdef _MSC_VER -# define wxUSE_GRAPHICS_CONTEXT 1 +#define wxUSE_GRAPHICS_CONTEXT 1 #else - // Disable support for other Windows compilers, enable it if your compiler - // comes with new enough SDK or you installed the headers manually. - // - // Notice that this will be set by configure under non-Windows platforms - // anyhow so the value there is not important. -# define wxUSE_GRAPHICS_CONTEXT 0 +// Disable support for other Windows compilers, enable it if your compiler +// comes with new enough SDK or you installed the headers manually. +// +// Notice that this will be set by configure under non-Windows platforms +// anyhow so the value there is not important. +#define wxUSE_GRAPHICS_CONTEXT 0 #endif // Enable wxGraphicsContext implementation using Cairo library. @@ -1141,6 +1141,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index 41797a4048..106918e031 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -983,6 +983,14 @@ # endif #endif /* !defined(wxUSE_PREFERENCES_EDITOR) */ +#ifndef wxUSE_PRIVATE_FONTS +# ifdef wxABORT_ON_CONFIG_ERROR +# error "wxUSE_PRIVATE_FONTS must be defined, please read comment near the top of this file." +# else +# define wxUSE_PRIVATE_FONTS 0 +# endif +#endif /* !defined(wxUSE_PRIVATE_FONTS) */ + #ifndef wxUSE_PRINTING_ARCHITECTURE # ifdef wxABORT_ON_CONFIG_ERROR # error "wxUSE_PRINTING_ARCHITECTURE must be defined, please read comment near the top of this file." @@ -2305,6 +2313,13 @@ # endif #endif /* wxUSE_PREFERENCES_EDITOR */ +#if wxUSE_PRIVATE_FONTS +# if !defined(__WXMSW__) && !defined(__WXGTK__) && !defined(__WXOSX__) +# undef wxUSE_PRIVATE_FONTS +# define wxUSE_PRIVATE_FONTS 0 +# endif +#endif /* wxUSE_PRIVATE_FONTS */ + #if wxUSE_MEDIACTRL # if !wxUSE_LONGLONG # ifdef wxABORT_ON_CONFIG_ERROR diff --git a/include/wx/font.h b/include/wx/font.h index 8236558201..354f458396 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -329,11 +329,10 @@ public: static wxFont *New(const wxString& strNativeFontDesc); // Load the font from the given file and return true on success or false on - // error (an error message will be logged in this case, unless there is no - // support for private fonts at all in the current port, in which case - // wxHAS_PRIVATE_FONTS will not be defined allowing to check for this at - // compile-time). + // error (an error message will be logged in this case). +#if wxUSE_PRIVATE_FONTS static bool AddPrivateFont(const wxString& filename); +#endif // wxUSE_PRIVATE_FONTS // comparison bool operator==(const wxFont& font) const; diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h index a8f8ce381f..4d1220617d 100644 --- a/include/wx/gtk/font.h +++ b/include/wx/gtk/font.h @@ -118,8 +118,4 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; -#ifdef wxHAVE_FONTCONFIG_2_8_0 - #define wxHAS_PRIVATE_FONTS 1 -#endif - #endif // _WX_GTK_FONT_H_ diff --git a/include/wx/gtk/setup0.h b/include/wx/gtk/setup0.h index 944260554e..e0155cee95 100644 --- a/include/wx/gtk/setup0.h +++ b/include/wx/gtk/setup0.h @@ -795,14 +795,14 @@ // notice that we can't use wxCHECK_VISUALC_VERSION() here as this file is // included from wx/platform.h before wxCHECK_VISUALC_VERSION() is defined #ifdef _MSC_VER -# define wxUSE_GRAPHICS_CONTEXT 1 +#define wxUSE_GRAPHICS_CONTEXT 1 #else - // Disable support for other Windows compilers, enable it if your compiler - // comes with new enough SDK or you installed the headers manually. - // - // Notice that this will be set by configure under non-Windows platforms - // anyhow so the value there is not important. -# define wxUSE_GRAPHICS_CONTEXT 0 +// Disable support for other Windows compilers, enable it if your compiler +// comes with new enough SDK or you installed the headers manually. +// +// Notice that this will be set by configure under non-Windows platforms +// anyhow so the value there is not important. +#define wxUSE_GRAPHICS_CONTEXT 0 #endif // Enable wxGraphicsContext implementation using Cairo library. @@ -1142,6 +1142,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/include/wx/motif/setup0.h b/include/wx/motif/setup0.h index dafcdaab77..f55fc8b14c 100644 --- a/include/wx/motif/setup0.h +++ b/include/wx/motif/setup0.h @@ -795,14 +795,14 @@ // notice that we can't use wxCHECK_VISUALC_VERSION() here as this file is // included from wx/platform.h before wxCHECK_VISUALC_VERSION() is defined #ifdef _MSC_VER -# define wxUSE_GRAPHICS_CONTEXT 1 +#define wxUSE_GRAPHICS_CONTEXT 1 #else - // Disable support for other Windows compilers, enable it if your compiler - // comes with new enough SDK or you installed the headers manually. - // - // Notice that this will be set by configure under non-Windows platforms - // anyhow so the value there is not important. -# define wxUSE_GRAPHICS_CONTEXT 0 +// Disable support for other Windows compilers, enable it if your compiler +// comes with new enough SDK or you installed the headers manually. +// +// Notice that this will be set by configure under non-Windows platforms +// anyhow so the value there is not important. +#define wxUSE_GRAPHICS_CONTEXT 0 #endif // Enable wxGraphicsContext implementation using Cairo library. @@ -1142,6 +1142,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/include/wx/msw/font.h b/include/wx/msw/font.h index 16dae838a9..eec24baedb 100644 --- a/include/wx/msw/font.h +++ b/include/wx/msw/font.h @@ -169,6 +169,4 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; -#define wxHAS_PRIVATE_FONTS 1 - #endif // _WX_FONT_H_ diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 9ac46699d6..5860054d87 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -795,14 +795,14 @@ // notice that we can't use wxCHECK_VISUALC_VERSION() here as this file is // included from wx/platform.h before wxCHECK_VISUALC_VERSION() is defined #ifdef _MSC_VER -# define wxUSE_GRAPHICS_CONTEXT 1 +#define wxUSE_GRAPHICS_CONTEXT 1 #else - // Disable support for other Windows compilers, enable it if your compiler - // comes with new enough SDK or you installed the headers manually. - // - // Notice that this will be set by configure under non-Windows platforms - // anyhow so the value there is not important. -# define wxUSE_GRAPHICS_CONTEXT 0 +// Disable support for other Windows compilers, enable it if your compiler +// comes with new enough SDK or you installed the headers manually. +// +// Notice that this will be set by configure under non-Windows platforms +// anyhow so the value there is not important. +#define wxUSE_GRAPHICS_CONTEXT 0 #endif // Enable wxGraphicsContext implementation using Cairo library. @@ -1142,6 +1142,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/include/wx/osx/font.h b/include/wx/osx/font.h index bd29cdf538..fcd82013f5 100644 --- a/include/wx/osx/font.h +++ b/include/wx/osx/font.h @@ -167,6 +167,4 @@ private: wxDECLARE_DYNAMIC_CLASS(wxFont); }; -#define wxHAS_PRIVATE_FONTS 1 - #endif // _WX_FONT_H_ diff --git a/include/wx/osx/setup0.h b/include/wx/osx/setup0.h index d920188567..75049f0e5e 100644 --- a/include/wx/osx/setup0.h +++ b/include/wx/osx/setup0.h @@ -1148,6 +1148,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index ebaaeba459..9f031a8c53 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -1138,6 +1138,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/include/wx/univ/setup0.h b/include/wx/univ/setup0.h index 9d8bed8509..069f9b156e 100644 --- a/include/wx/univ/setup0.h +++ b/include/wx/univ/setup0.h @@ -794,14 +794,14 @@ // notice that we can't use wxCHECK_VISUALC_VERSION() here as this file is // included from wx/platform.h before wxCHECK_VISUALC_VERSION() is defined #ifdef _MSC_VER -# define wxUSE_GRAPHICS_CONTEXT 1 +#define wxUSE_GRAPHICS_CONTEXT 1 #else - // Disable support for other Windows compilers, enable it if your compiler - // comes with new enough SDK or you installed the headers manually. - // - // Notice that this will be set by configure under non-Windows platforms - // anyhow so the value there is not important. -# define wxUSE_GRAPHICS_CONTEXT 0 +// Disable support for other Windows compilers, enable it if your compiler +// comes with new enough SDK or you installed the headers manually. +// +// Notice that this will be set by configure under non-Windows platforms +// anyhow so the value there is not important. +#define wxUSE_GRAPHICS_CONTEXT 0 #endif // Enable wxGraphicsContext implementation using Cairo library. @@ -1141,6 +1141,16 @@ // Recommended setting: 1 (but can be safely disabled if you don't use it) #define wxUSE_PREFERENCES_EDITOR 1 +// wxFont::AddPrivateFont() allows to use fonts not installed on the system by +// loading them from font files during run-time. +// +// Default is 1 except under Unix where it will be turned off by configure if +// the required libraries are not available or not new enough. +// +// Recommended setting: 1 (but can be safely disabled if you don't use it and +// want to avoid extra dependencies under Linux, for example). +#define wxUSE_PRIVATE_FONTS 1 + // wxRichToolTip is a customizable tooltip class which has more functionality // than the stock (but native, unlike this class) wxToolTip. // diff --git a/interface/wx/font.h b/interface/wx/font.h index 9f7c37708f..e798a95d84 100644 --- a/interface/wx/font.h +++ b/interface/wx/font.h @@ -686,10 +686,10 @@ public: false and log an error message explaining the problem if this requirement is not satisfied either at compile- or run-time. - Currently this method is implemented for all major platforms but you - may also test for @c wxHAS_PRIVATE_FONTS preprocessor symbol: if it is - not defined, this function is not implemented at all and simply always - returns false. + Currently this method is implemented for all major platforms (subject + to having Pango 1.38 or later when running configure under Unix) and + @c wxUSE_PRIVATE_FONTS is always set to 0 under the other platforms, + making this function unavailable at compile-time. @return @true if the font was added and can now be used. diff --git a/samples/font/font.cpp b/samples/font/font.cpp index 6b5110064f..022c0a8c6d 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -397,7 +397,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) wxT("Find font for en&coding...\tCtrl-C"), wxT("Find font families for given encoding")); -#ifdef wxHAS_PRIVATE_FONTS +#if wxUSE_PRIVATE_FONTS // Try to use a private font, under most platforms we just look for it in // the current directory but under OS X it must be in a specific location // so look for it there. @@ -433,7 +433,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) "Select private font", "Select a font available only in this application"); } -#endif // wxHAS_PRIVATE_FONTS +#endif // wxUSE_PRIVATE_FONTS // now append the freshly created menu to the menu bar... diff --git a/setup.h.in b/setup.h.in index e173a50227..b2de2783c3 100644 --- a/setup.h.in +++ b/setup.h.in @@ -468,6 +468,8 @@ #define wxUSE_PREFERENCES_EDITOR 0 +#define wxUSE_PRIVATE_FONTS 0 + #define wxUSE_RICHTOOLTIP 0 #define wxUSE_SASH 0 @@ -833,10 +835,6 @@ */ #define wxUSE_PLUGINS 0 -/* - * Use FontConfig library for private fonts support in wxFont. - */ -#undef wxHAVE_FONTCONFIG_2_8_0 /* * Use GTK print for printing under GTK+ 2.10+ */ diff --git a/setup.h_vms b/setup.h_vms index e9958e410d..d1f7842057 100644 --- a/setup.h_vms +++ b/setup.h_vms @@ -902,14 +902,6 @@ typedef pid_t GPid; * Use SDL for audio (Unix) */ #define wxUSE_LIBSDL 0 -/* - * Use FontConfig library for private fonts support in wxFont. - */ -#ifdef VMS_GTK2 -#define wxHAVE_FONTCONFIG_2_8_0 1 -#else -#undef wxHAVE_FONTCONFIG_2_8_0 -#endif /* * Use GTK print for printing under GTK+ 2.10+ */ diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index dcb899a9ae..ea249bad90 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -1136,16 +1136,3 @@ bool wxFromString(const wxString& str, wxFontBase *font) return font->SetNativeFontInfo(str); } - -#ifndef wxHAS_PRIVATE_FONTS - -// Adding private fonts is not supported on this platform, so provide the -// functions that would be used, but make them no-ops that return a code -// that indicates failure. - -bool wxFontBase::AddPrivateFont(const wxString& WXUNUSED(filename)) -{ - return false; -} - -#endif // !wxHAS_PRIVATE_FONTS diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index b14f68b218..96403a8bbb 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -558,7 +558,7 @@ bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const // Support for adding private fonts // ---------------------------------------------------------------------------- -#ifdef wxHAS_PRIVATE_FONTS +#if wxUSE_PRIVATE_FONTS #include "wx/fontenum.h" #include "wx/module.h" @@ -649,4 +649,4 @@ bool wxFontBase::AddPrivateFont(const wxString& filename) return true; } -#endif // wxHAS_PRIVATE_FONTS +#endif // wxUSE_PRIVATE_FONTS diff --git a/src/msw/font.cpp b/src/msw/font.cpp index 4ef7642035..27dc7cfed1 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -1089,6 +1089,8 @@ bool wxFont::IsFixedWidth() const // Private fonts support // ---------------------------------------------------------------------------- +#if wxUSE_PRIVATE_FONTS + namespace { @@ -1131,3 +1133,5 @@ bool wxFontBase::AddPrivateFont(const wxString& filename) gs_privateFontFileNames.Add(filename); return true; } + +#endif // wxUSE_PRIVATE_FONTS diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 003eefd41e..9e87c937d1 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -963,6 +963,8 @@ wxGDIPlusBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo, // Support for adding private fonts //----------------------------------------------------------------------------- +#if wxUSE_PRIVATE_FONTS + namespace { @@ -974,6 +976,8 @@ Gdiplus::FontFamily* gs_pFontFamily = NULL; // This function is defined in src/msw/font.cpp. extern const wxArrayString& wxGetPrivateFontFileNames(); +#endif // wxUSE_PRIVATE_FONTS + //----------------------------------------------------------------------------- // wxGDIPlusFont implementation //----------------------------------------------------------------------------- @@ -985,6 +989,7 @@ wxGDIPlusFontData::Init(const wxString& name, const wxColour& col, Unit fontUnit) { +#if wxUSE_PRIVATE_FONTS // If the user has registered any private fonts, they should be used in // preference to any system-wide ones. m_font = NULL; @@ -1009,7 +1014,10 @@ wxGDIPlusFontData::Init(const wxString& name, } if ( !m_font ) +#endif // wxUSE_PRIVATE_FONTS + { m_font = new Font(name.wc_str(), size, style, fontUnit); + } m_textBrush = new SolidBrush(wxColourToColor(col)); } @@ -2315,6 +2323,7 @@ void wxGDIPlusRenderer::Load() wxLogTrace("gdiplus", "successfully initialized GDI+"); m_loaded = 1; +#if wxUSE_PRIVATE_FONTS // Make private fonts available to GDI+, if any. const wxArrayString& privateFonts = wxGetPrivateFontFileNames(); const size_t n = privateFonts.size(); @@ -2329,6 +2338,7 @@ void wxGDIPlusRenderer::Load() gs_pFontFamily = new Gdiplus::FontFamily[n]; } +#endif // wxUSE_PRIVATE_FONTS } else { @@ -2344,6 +2354,7 @@ void wxGDIPlusRenderer::Unload() GdiplusShutdown(m_gditoken); m_gditoken = 0; +#if wxUSE_PRIVATE_FONTS if ( gs_privateFonts ) { delete gs_privateFonts; @@ -2352,6 +2363,7 @@ void wxGDIPlusRenderer::Unload() delete[] gs_pFontFamily; gs_pFontFamily = NULL; } +#endif // wxUSE_PRIVATE_FONTS } m_loaded = -1; // next Load() will try again } diff --git a/src/osx/fontutil.cpp b/src/osx/fontutil.cpp index 5cf015bcda..1f44f778c9 100644 --- a/src/osx/fontutil.cpp +++ b/src/osx/fontutil.cpp @@ -69,6 +69,8 @@ wxString wxNativeEncodingInfo::ToString() const // Private Fonts // ---------------------------------------------------------------------------- +#if wxUSE_PRIVATE_FONTS + // On OSX one can provide private fonts simply by putting the font files in // with the resources in your application bundle. So the API for adding fonts // does not do anything except checking that the file you pass to it actually @@ -95,6 +97,8 @@ bool wxFontBase::AddPrivateFont(const wxString& filename) return true; } +#endif // wxUSE_PRIVATE_FONTS + // ---------------------------------------------------------------------------- // helper functions // ----------------------------------------------------------------------------