+#include "wx/cocoa/string.h"
+#include "wx/cocoa/private/fontfactory.h"
+#include "wx/cocoa/autorelease.h"
+
+#include <AppKit/NSFont.h>
+#include <AppKit/NSFontManager.h>
+
+// Helper methods for NSFont/wxNativeFontInfo
+static NSFont* GetNSFontForNativeFontInfo(const wxNativeFontInfo &info);
+static void UpdateNativeFontInfoWithNSFont(wxNativeFontInfo &info, NSFont *cocoaNSFont);
+static wxNativeFontInfo MakeNativeFontInfoForNSFont(NSFont *cocoaNSFont, bool underlined = false);
+static wxNativeFontInfo MakeNativeFontInfo(int size, int family, int style, int weight, bool underlined, const wxString& faceName, wxFontEncoding encoding);
+
+/*! @discussion
+ Due to 2.8 ABI compatibility concerns we probably don't want to change wxNativeFontInfo
+ although this may be unfounded because this class is supposed to be internal as is
+ wxNativeFontInfo so anyone who subclassed it or created one without going through
+ wxFont should expect what they get (i.e. horrible breakage)
+ There's a concern that wxFontRefData was in the public header when 2.8 shipped so
+ it's possible that someone did subclass it to get better font behavior.
+
+ For right now, the plan is to write it strictly ABI compatible with 2.8 and eventually
+ to enhance it in trunk to accurately represent font attributes as Cocoa sees them.
+
+ I'd like to let at least one 2.8 release go out the door and get feedback as to whether
+ this is going to be a problem or not. If so, we'll keep it strictly ABI compatible.
+ If not, we'll update it.
+ */
+class WXDLLEXPORT wxFontRefData: public wxGDIRefData
+{
+ friend class WXDLLIMPEXP_FWD_CORE wxFont;
+public:
+ wxFontRefData()
+ : m_cocoaNSFont(nil)
+ , m_info(MakeNativeFontInfo(10, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
+ wxT("Geneva"), wxFONTENCODING_DEFAULT))
+ {
+ CreateNSFontAndUpdateInfo();
+ }
+
+ wxFontRefData(const wxFontRefData& data)
+ : wxGDIRefData()
+ , m_cocoaNSFont([data.m_cocoaNSFont retain])
+ , m_info(data.m_info)
+ {
+ }
+
+ wxFontRefData(NSFont *cocoaNSFont, bool underlined)
+ : wxGDIRefData()
+ , m_cocoaNSFont([cocoaNSFont retain])
+ , m_info(MakeNativeFontInfoForNSFont(m_cocoaNSFont, underlined))
+ {
+ }
+
+ wxFontRefData(const wxNativeFontInfo& info)
+ : wxGDIRefData()
+ , m_cocoaNSFont(nil)
+ , m_info(info)
+ {
+ CreateNSFontAndUpdateInfo();
+ }
+
+ wxFontRefData(int size,
+ int family,
+ int style,
+ int weight,
+ bool underlined,
+ const wxString& faceName,
+ wxFontEncoding encoding)
+ : m_cocoaNSFont(nil)
+ , m_info(MakeNativeFontInfo(size, family, style, weight, underlined, faceName, encoding))
+ {
+ CreateNSFontAndUpdateInfo();
+ }
+
+ virtual ~wxFontRefData();
+protected:
+ /*! @abstract common part of some ctors
+ @discussion
+ This is a leftover of sorts from the old stub code.
+ FIXME: Remove from trunk
+ */
+ void Init(int size,
+ int family,
+ int style,
+ int weight,
+ bool underlined,
+ const wxString& faceName,
+ wxFontEncoding encoding);
+
+ /*! @discussion
+ Uses the native font info to create an NSFont and then updates that info with
+ the attributes of the font. This is necessary because, for example, a font
+ can be created with an empty faceName in which case some concrete typeface must
+ be chosen.
+ We choose to handle this by first initializing the wxNativeFontInfo with the
+ properties as given by the user and then creating the NSFont and updating
+ the wxNativeFontInfo to match the NSFont.
+ */
+ void CreateNSFontAndUpdateInfo()
+ {
+ wxAutoNSAutoreleasePool pool;
+ [m_cocoaNSFont release];
+ m_cocoaNSFont = [GetNSFontForNativeFontInfo(m_info) retain];
+ UpdateNativeFontInfoWithNSFont(m_info, m_cocoaNSFont);
+ }
+
+ // font characterstics
+ NSFont *m_cocoaNSFont;
+ wxNativeFontInfo m_info;
+
+public:
+};
+
+NSString *GetFamilyName(wxFontFamily family)
+{
+ switch(family)
+ {
+ case wxFONTFAMILY_DEFAULT:
+ default:
+ return @"Times";
+ case wxFONTFAMILY_DECORATIVE:
+ case wxFONTFAMILY_ROMAN:
+ case wxFONTFAMILY_SCRIPT:
+ return @"Times";
+ case wxFONTFAMILY_SWISS:
+ return @"Lucida Grande";
+ case wxFONTFAMILY_MODERN:
+ case wxFONTFAMILY_TELETYPE:
+ return @"Monaco";
+ };
+}
+// Returns an NSFont given the native font info
+// NOTE: It is not considered alloc'd (i.e. this is a get method not an alloc/new method)
+static NSFont* GetNSFontForNativeFontInfo(const wxNativeFontInfo &info)
+{
+ if(!info.faceName.empty())
+ {
+ NSFont *font = [NSFont fontWithName:wxNSStringWithWxString(info.faceName) size:info.pointSize];
+ // TODO: use NSFontManager to mix in the weights and whatnot
+ if(font != nil)
+ return font;
+ // To err or not to err?
+ }
+ // No font with that face name or no face name
+
+ NSFontTraitMask cocoaTraits = 0;
+ int cocoaWeight = 5;
+ NSFont *font = [[NSFontManager sharedFontManager] fontWithFamily:GetFamilyName(info.family) traits:cocoaTraits weight:cocoaWeight size:info.pointSize];
+ return font;
+}
+
+/*! @discussion
+ Updates all fields of @a info except for underlined which is not a property of NSFont.
+ */
+static void UpdateNativeFontInfoWithNSFont(wxNativeFontInfo &info, NSFont *cocoaNSFont)
+{
+ info.pointSize = [cocoaNSFont pointSize];
+
+ // FIXME: We could maybe improve on this?
+ info.family = wxFONTFAMILY_DEFAULT;
+
+ // FIXME: italicAngle might indicate a slanted rather than truly italic font?
+ info.style = [cocoaNSFont italicAngle] == 0.0?wxFONTSTYLE_NORMAL:wxFONTSTYLE_ITALIC;
+
+ int cocoaWeight = [[NSFontManager sharedFontManager] weightOfFont:cocoaNSFont];
+ if(cocoaWeight < 5)
+ info.weight = wxFONTWEIGHT_LIGHT;
+ else if(cocoaWeight < 9)
+ info.weight = wxFONTWEIGHT_NORMAL;
+ else
+ info.weight = wxFONTWEIGHT_BOLD;
+
+ // FIXME: Is this right? I think so.
+ info.faceName = wxStringWithNSString([cocoaNSFont fontName]);
+
+ // TODO: Translate NSStringEncoding to wxFontEncoding
+ info.encoding = wxFONTENCODING_SYSTEM;
+}
+
+/*! @discussion
+ Creates a new generic wxNativeFontInfo from an NSFont and an underlined flag.
+ Uses UpdateNativeFontInfoWithNSFont to do the work and sets the underlined field
+ of wxNativeFontInfo to the @a underlined argument.
+ */
+static wxNativeFontInfo MakeNativeFontInfoForNSFont(NSFont *cocoaNSFont, bool underlined)
+{
+ wxNativeFontInfo info;
+ UpdateNativeFontInfoWithNSFont(info, cocoaNSFont);
+
+ // NSFont are never underlined.. that's a function of the drawing system
+ info.underlined = underlined;
+
+ return info;
+}
+
+//#include "_font_test_2_8_abi_compat.h"
+