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 0000000000..82d77fe5f3
Binary files /dev/null and b/samples/font/wxprivate.ttf differ
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
// ----------------------------------------------------------------------------