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 // ----------------------------------------------------------------------------