X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e9576ca53db96b462ed4c0b4bdf47d64c40203e4..9b7835a516d1acdeb007bed0c5bb80cae1643416:/src/mac/carbon/font.cpp diff --git a/src/mac/carbon/font.cpp b/src/mac/carbon/font.cpp index 493a6a25ba..0fcdd8ad72 100644 --- a/src/mac/carbon/font.cpp +++ b/src/mac/carbon/font.cpp @@ -1,116 +1,470 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: font.cpp +// Name: src/mac/carbon/font.cpp // Purpose: wxFont class -// Author: AUTHOR +// Author: Stefan Csomor // Modified by: -// Created: ??/??/98 +// Created: 1998-01-01 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) Stefan Csomor +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "font.h" -#endif +#include "wx/wxprec.h" -#include "wx/defs.h" -#include "wx/string.h" #include "wx/font.h" -#include "wx/gdicmn.h" -#if !USE_SHARED_LIBRARIES -IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) +#ifndef WX_PRECOMP + #include "wx/string.h" + #include "wx/utils.h" + #include "wx/intl.h" + #include "wx/gdicmn.h" + #include "wx/log.h" #endif -wxFontRefData::wxFontRefData() +#include "wx/fontutil.h" +#include "wx/graphics.h" + +#include "wx/mac/private.h" + +#ifndef __DARWIN__ +#include +#endif + + +IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) + + +class WXDLLEXPORT wxFontRefData: public wxGDIRefData { - m_style = 0; - m_pointSize = 0; - m_family = 0; - m_style = 0; - m_weight = 0; - m_underlined = 0; - m_faceName = ""; -/* TODO - m_hFont = 0; -*/ -} + friend class WXDLLEXPORT wxFont; + +public: + wxFontRefData() + : m_fontId(0) + , m_pointSize(10) + , m_family(wxDEFAULT) + , m_style(wxNORMAL) + , m_weight(wxNORMAL) + , m_underlined(false) + , m_faceName(wxT("applicationfont")) + , m_encoding(wxFONTENCODING_DEFAULT) + , m_macFontFamily(0) + , m_macFontSize(0) + , m_macFontStyle(0) + , m_macATSUStyle(0) + , m_macATSUFontID(0) + { + Init(m_pointSize, m_family, m_style, m_weight, + m_underlined, m_faceName, m_encoding); + } + + wxFontRefData(const wxFontRefData& data) + : wxGDIRefData() + , m_fontId(data.m_fontId) + , m_pointSize(data.m_pointSize) + , m_family(data.m_family) + , m_style(data.m_style) + , m_weight(data.m_weight) + , m_underlined(data.m_underlined) + , m_faceName(data.m_faceName) + , m_encoding(data.m_encoding) + , m_macFontFamily(data.m_macFontFamily) + , m_macFontSize(data.m_macFontSize) + , m_macFontStyle(data.m_macFontStyle) + , m_macATSUStyle(0) + , m_macATSUFontID(data.m_macATSUFontID) + { + Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight, + data.m_underlined, data.m_faceName, data.m_encoding); + } + + wxFontRefData(int size, + int family, + int style, + int weight, + bool underlined, + const wxString& faceName, + wxFontEncoding encoding) + : m_fontId(0) + , m_pointSize(size) + , m_family(family) + , m_style(style) + , m_weight(weight) + , m_underlined(underlined) + , m_faceName(faceName) + , m_encoding(encoding) + , m_macFontFamily(0) + , m_macFontSize(0) + , m_macFontStyle(0) + , m_macATSUStyle(0) + , m_macATSUFontID(0) + { + Init(size, family, style, weight, underlined, faceName, encoding); + } -wxFontRefData::wxFontRefData(const wxFontRefData& data) + virtual ~wxFontRefData(); + + void SetNoAntiAliasing( bool no = true ) + { m_noAA = no; } + + bool GetNoAntiAliasing() const + { return m_noAA; } + + void MacFindFont(); + +protected: + // common part of all ctors + void Init(int size, + int family, + int style, + int weight, + bool underlined, + const wxString& faceName, + wxFontEncoding encoding); + + // font characterstics + int m_fontId; + int m_pointSize; + int m_family; + int m_style; + int m_weight; + bool m_underlined; + wxString m_faceName; + wxFontEncoding m_encoding; + bool m_noAA; // No anti-aliasing + +public: + FMFontFamily m_macFontFamily; + FMFontSize m_macFontSize; + FMFontStyle m_macFontStyle; + + // ATSU Font Information + + // this is split into an ATSU font id that may + // contain some styles (special bold fonts etc) and + // these are the additional qd styles that are not + // included in the ATSU font id + ATSUStyle m_macATSUStyle ; + ATSUFontID m_macATSUFontID; + FMFontStyle m_macATSUAdditionalQDStyles ; + + // for true themeing support we must store the correct font + // information here, as this speeds up and optimizes rendering + ThemeFontID m_macThemeFontID ; + + wxNativeFontInfo m_info; +}; + +#define M_FONTDATA ((wxFontRefData*)m_refData) + + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxFontRefData +// ---------------------------------------------------------------------------- + +void wxFontRefData::Init(int pointSize, + int family, + int style, + int weight, + bool underlined, + const wxString& faceName, + wxFontEncoding encoding) { - m_style = data.m_style; - m_pointSize = data.m_pointSize; - m_family = data.m_family; - m_style = data.m_style; - m_weight = data.m_weight; - m_underlined = data.m_underlined; - m_faceName = data.m_faceName; -/* TODO - m_hFont = 0; -*/ + m_style = style; + m_pointSize = pointSize; + m_family = family; + m_style = style; + m_weight = weight; + m_underlined = underlined; + m_faceName = faceName; + m_encoding = encoding; + + m_macFontFamily = 0 ; + m_macFontSize = 0; + m_macFontStyle = 0; + m_macATSUFontID = 0; + m_macATSUAdditionalQDStyles = 0 ; + m_macATSUStyle = NULL ; + + m_macThemeFontID = kThemeCurrentPortFont ; + m_noAA = false; } wxFontRefData::~wxFontRefData() { - // TODO: delete font data + if ( m_macATSUStyle ) + { + ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle); + m_macATSUStyle = NULL ; + } +} + +void wxFontRefData::MacFindFont() +{ + OSStatus status ; + + Str255 qdFontName ; + if ( m_macThemeFontID != kThemeCurrentPortFont ) + { + Style style ; + GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style ); + m_macFontStyle = style ; + m_faceName = wxMacMakeStringFromPascal( qdFontName ); + if ( m_macFontStyle & bold ) + m_weight = wxBOLD ; + else + m_weight = wxNORMAL ; + if ( m_macFontStyle & italic ) + m_style = wxITALIC ; + if ( m_macFontStyle & underline ) + m_underlined = true ; + m_pointSize = m_macFontSize ; +#ifndef __LP64__ + m_macFontFamily = FMGetFontFamilyFromName( qdFontName ); +#endif + } + else + { + if ( m_faceName.empty() ) + { + if ( m_family == wxDEFAULT ) + { +#ifndef __LP64__ + m_macFontFamily = GetAppFont(); + FMGetFontFamilyName(m_macFontFamily,qdFontName); + m_faceName = wxMacMakeStringFromPascal( qdFontName ); +#endif + } + else + { + switch ( m_family ) + { + case wxSCRIPT : + case wxROMAN : + case wxDECORATIVE : + m_faceName = wxT("Times"); + break ; + + case wxSWISS : + m_faceName = wxT("Lucida Grande"); + break ; + + case wxMODERN : + case wxTELETYPE: + m_faceName = wxT("Monaco"); + break ; + + default: + m_faceName = wxT("Times"); + break ; + } +#ifndef __LP64__ + wxMacStringToPascal( m_faceName , qdFontName ); + m_macFontFamily = FMGetFontFamilyFromName( qdFontName ); + if ( m_macFontFamily == kInvalidFontFamily ) + { + wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName.c_str() ); + m_macFontFamily = GetAppFont(); + } +#endif + } + } + else + { +#ifndef __LP64__ + if ( m_faceName == wxT("systemfont") ) + m_macFontFamily = GetSysFont(); + else if ( m_faceName == wxT("applicationfont") ) + m_macFontFamily = GetAppFont(); + else +#else + if ( m_faceName == wxT("systemfont") ) + m_faceName = wxT("Lucida Grande"); + else if ( m_faceName == wxT("applicationfont") ) + m_faceName = wxT("Lucida Grande"); +#endif + { + wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() ); + ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault ); + + // ATSFontFamilyRef is an unsigned type, so check against max + // for an invalid value, not -1. + if ( atsfamily == 0xffffffff ) + { + wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName ); + m_macFontFamily = GetAppFont(); + } + else + m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily ); + } + } + + m_macFontStyle = 0; + if (m_weight == wxBOLD) + m_macFontStyle |= bold; + if (m_style == wxITALIC || m_style == wxSLANT) + m_macFontStyle |= italic; + if (m_underlined) + m_macFontStyle |= underline; + m_macFontSize = m_pointSize ; + } + + // we try to get as much styles as possible into ATSU + + + // ATSUFontID and FMFont are equivalent + FMFontStyle intrinsicStyle = 0 ; +#ifndef __LP64__ + status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle); + wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") ); +#endif + m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle ); + + if ( m_macATSUStyle ) + { + ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle); + m_macATSUStyle = NULL ; + } + + status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle); + wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ); + + ATSUAttributeTag atsuTags[] = + { + kATSUFontTag , + kATSUSizeTag , + kATSUVerticalCharacterTag, + kATSUQDBoldfaceTag , + kATSUQDItalicTag , + kATSUQDUnderlineTag , + kATSUQDCondensedTag , + kATSUQDExtendedTag , + }; + ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { + sizeof( ATSUFontID ) , + sizeof( Fixed ) , + sizeof( ATSUVerticalCharacterType), + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( Boolean ) , + sizeof( Boolean ) , + }; + + Boolean kTrue = true ; + Boolean kFalse = false ; + + Fixed atsuSize = IntToFixed( m_macFontSize ); + ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; + ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { + &m_macATSUFontID , + &atsuSize , + &kHorizontal, + (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse , + }; + + status = ::ATSUSetAttributes( + (ATSUStyle)m_macATSUStyle, + sizeof(atsuTags) / sizeof(ATSUAttributeTag) , + atsuTags, atsuSizes, atsuValues); + + wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); +} + +// ---------------------------------------------------------------------------- +// wxFont +// ---------------------------------------------------------------------------- + +bool wxFont::Create(const wxNativeFontInfo& info) +{ + return Create( + info.pointSize, info.family, info.style, info.weight, + info.underlined, info.faceName, info.encoding ); } -wxFont::wxFont() +wxFont::wxFont(const wxString& fontdesc) { - if ( wxTheFontList ) - wxTheFontList->Append(this); + wxNativeFontInfo info; + if ( info.FromString(fontdesc) ) + (void)Create(info); } -wxFont::wxFont(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName) +bool wxFont::Create(int pointSize, + int family, + int style, + int weight, + bool underlined, + const wxString& faceName, + wxFontEncoding encoding) { - Create(pointSize, family, style, weight, underlined, faceName); + UnRef(); + + m_refData = new wxFontRefData( + pointSize, family, style, weight, + underlined, faceName, encoding); + + RealizeResource(); - if ( wxTheFontList ) - wxTheFontList->Append(this); + return true; } -bool wxFont::Create(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName) +bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) { UnRef(); - m_refData = new wxFontRefData; - M_FONTDATA->m_family = family; - M_FONTDATA->m_style = style; - M_FONTDATA->m_weight = weight; - M_FONTDATA->m_pointSize = pointSize; - M_FONTDATA->m_underlined = underlined; - M_FONTDATA->m_faceName = faceName; + m_refData = new wxFontRefData( + 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, + false, wxEmptyString, wxFONTENCODING_DEFAULT ); + M_FONTDATA->m_macThemeFontID = themeFontID ; RealizeResource(); - return TRUE; + return true; } wxFont::~wxFont() { - if (wxTheFontList) - wxTheFontList->DeleteObject(this); } bool wxFont::RealizeResource() { - // TODO: create the font (if there is a native font object) - return FALSE; + M_FONTDATA->MacFindFont(); + + return true; +} + +void wxFont::SetEncoding(wxFontEncoding encoding) +{ + Unshare(); + + M_FONTDATA->m_encoding = encoding; + + RealizeResource(); } void wxFont::Unshare() { - // Don't change shared data - if (!m_refData) + // Don't change shared data + if (!m_refData) { - m_refData = new wxFontRefData(); - } + m_refData = new wxFontRefData(); + } else { - wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData); - UnRef(); - m_refData = ref; - } + wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData); + UnRef(); + m_refData = ref; + } } void wxFont::SetPointSize(int pointSize) @@ -149,13 +503,15 @@ void wxFont::SetWeight(int weight) RealizeResource(); } -void wxFont::SetFaceName(const wxString& faceName) +bool wxFont::SetFaceName(const wxString& faceName) { Unshare(); M_FONTDATA->m_faceName = faceName; RealizeResource(); + + return wxFontBase::SetFaceName(faceName); } void wxFont::SetUnderlined(bool underlined) @@ -167,78 +523,146 @@ void wxFont::SetUnderlined(bool underlined) RealizeResource(); } -wxString wxFont::GetFamilyString() const -{ - wxString fam(""); - switch (GetFamily()) - { - case wxDECORATIVE: - fam = "wxDECORATIVE"; - break; - case wxROMAN: - fam = "wxROMAN"; - break; - case wxSCRIPT: - fam = "wxSCRIPT"; - break; - case wxSWISS: - fam = "wxSWISS"; - break; - case wxMODERN: - fam = "wxMODERN"; - break; - case wxTELETYPE: - fam = "wxTELETYPE"; - break; - default: - fam = "wxDEFAULT"; - break; - } - return fam; -} - -/* New font system */ +void wxFont::SetNoAntiAliasing( bool no ) +{ + Unshare(); + + M_FONTDATA->SetNoAntiAliasing( no ); + + RealizeResource(); +} + +// ---------------------------------------------------------------------------- +// accessors +// ---------------------------------------------------------------------------- + +// TODO: insert checks everywhere for M_FONTDATA == NULL! + +int wxFont::GetPointSize() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_pointSize; +} + +wxSize wxFont::GetPixelSize() const +{ +#if wxUSE_GRAPHICS_CONTEXT + // TODO: consider caching the value + wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL); + dc->SetFont(*(wxFont *)this,*wxBLACK); + wxDouble width, height = 0; + dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL); + return wxSize((int)width, (int)height); +#else + return wxFontBase::GetPixelSize(); +#endif +} + +int wxFont::GetFamily() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_family; +} + +int wxFont::GetStyle() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_style; +} + +int wxFont::GetWeight() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_weight; +} + +bool wxFont::GetUnderlined() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") ); + + return M_FONTDATA->m_underlined; +} + wxString wxFont::GetFaceName() const { - wxString str(""); - if (M_FONTDATA) - str = M_FONTDATA->m_faceName ; - return str; + wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") ); + + return M_FONTDATA->m_faceName; } -wxString wxFont::GetStyleString() const +wxFontEncoding wxFont::GetEncoding() const { - wxString styl(""); - switch (GetStyle()) - { - case wxITALIC: - styl = "wxITALIC"; - break; - case wxSLANT: - styl = "wxSLANT"; - break; - default: - styl = "wxNORMAL"; - break; - } - return styl; + wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") ); + + return M_FONTDATA->m_encoding; } -wxString wxFont::GetWeightString() const +bool wxFont::GetNoAntiAliasing() const { - wxString w(""); - switch (GetWeight()) - { - case wxBOLD: - w = "wxBOLD"; - break; - case wxLIGHT: - w = "wxLIGHT"; - break; - default: - w = "wxNORMAL"; - break; - } - return w; + wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") ); + + return M_FONTDATA->m_noAA; +} + +short wxFont::MacGetFontNum() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontFamily; +} + +short wxFont::MacGetFontSize() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontSize; } +wxByte wxFont::MacGetFontStyle() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontStyle; +} + +wxUint32 wxFont::MacGetATSUFontID() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUFontID; +} + +void * wxFont::MacGetATSUStyle() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUStyle; +} + +wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUAdditionalQDStyles; +} + +wxUint16 wxFont::MacGetThemeFontID() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macThemeFontID; +} + +const wxNativeFontInfo * wxFont::GetNativeFontInfo() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") ); + wxCHECK_MSG( Ok(), NULL, wxT("invalid font") ); + + M_FONTDATA->m_info.InitFromFont(*this); + + return &(M_FONTDATA->m_info); +}