]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fontcmn.cpp
Silence warning about truncation since the comment says it ok
[wxWidgets.git] / src / common / fontcmn.cpp
index ad280cef8e4c2ddba8e9067ab7417feef10737d5..bddce519a278ceb9fbed95026a13fed3c666c752 100644 (file)
@@ -5,8 +5,8 @@
 // Modified by:
 // Created:     20.09.99
 // RCS-ID:      $Id$
-// Copyright:   (c) wxWindows team
-// Licence:     wxWindows license
+// Copyright:   (c) wxWidgets team
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "fontbase.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-    #pragma hdrstop
+#pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
+    #include "wx/dc.h"
     #include "wx/font.h"
+    #include "wx/intl.h"
+    #include "wx/dcscreen.h"
 #endif // WX_PRECOMP
 
 #include "wx/gdicmn.h"
+
+#if defined(__WXMSW__)
+  #include  "wx/msw/private.h"  // includes windows.h for LOGFONT
+  #include  "wx/msw/winundef.h"
+#endif
+
 #include "wx/fontutil.h" // for wxNativeFontInfo
 #include "wx/fontmap.h"
 
 // implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// helper functions
+// ----------------------------------------------------------------------------
+
+static void AdjustFontSize(wxFont& font, wxDC& dc, const wxSize& pixelSize)
+{
+    int currentSize = font.GetPointSize();
+    int largestGood = 0;
+    int smallestBad = 0;
+
+    bool initialGoodFound = false;
+    bool initialBadFound = false;
+
+    while (currentSize > 0)
+    {
+        dc.SetFont(font);
+
+        // if currentSize (in points) results in a font that is smaller
+        // than required by pixelSize it is considered a good size
+        if (dc.GetCharHeight() <= pixelSize.GetHeight() &&
+                (!pixelSize.GetWidth() ||
+                 dc.GetCharWidth() <= pixelSize.GetWidth()))
+        {
+            largestGood = currentSize;
+            initialGoodFound = true;
+        }
+        else
+        {
+            smallestBad = currentSize;
+            initialBadFound = true;
+        }
+        if (!initialGoodFound)
+        {
+            currentSize /= 2;
+        }
+        else if (!initialBadFound)
+        {
+            currentSize *= 2;
+        }
+        else
+        {
+            int distance = smallestBad - largestGood;
+            if (distance == 1)
+                break;
+
+            currentSize = largestGood + distance / 2;
+        }
+
+        font.SetPointSize(currentSize);
+    }
+
+    if (currentSize != largestGood)
+        font.SetPointSize(largestGood);
+}
+
 // ----------------------------------------------------------------------------
 // wxFontBase
 // ----------------------------------------------------------------------------
 
 wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
 
+/* static */
+void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
+{
+    // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
+    // and, besides, using this value here doesn't make any sense
+    wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
+                 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
+
+    ms_encodingDefault = encoding;
+}
+
+wxFontBase::~wxFontBase()
+{
+    // this destructor is required for Darwin
+}
+
 /* static */
 wxFont *wxFontBase::New(int size,
                         int family,
@@ -60,6 +136,89 @@ wxFont *wxFontBase::New(int size,
     return new wxFont(size, family, style, weight, underlined, face, encoding);
 }
 
+static inline int flags2Style(int flags)
+{
+    return flags & wxFONTFLAG_ITALIC
+                    ? wxFONTSTYLE_ITALIC
+                    : flags & wxFONTFLAG_SLANT
+                        ? wxFONTSTYLE_SLANT
+                        : wxFONTSTYLE_NORMAL;
+}
+
+static inline int flags2Weight(int flags)
+{
+    return flags & wxFONTFLAG_LIGHT
+                    ? wxFONTWEIGHT_LIGHT
+                    : flags & wxFONTFLAG_BOLD
+                        ? wxFONTWEIGHT_BOLD
+                        : wxFONTWEIGHT_NORMAL;
+}
+
+static inline bool flags2Underlined(int flags)
+{
+    return (flags & wxFONTFLAG_UNDERLINED) != 0;
+}
+
+/* static */
+wxFont *wxFontBase::New(int pointSize,
+                        wxFontFamily family,
+                        int flags,
+                        const wxString& face,
+                        wxFontEncoding encoding)
+{
+    return New(pointSize, family, flags2Style(flags), flags2Weight(flags),
+               flags2Underlined(flags), face, encoding);
+}
+
+/* static */
+wxFont *wxFontBase::New(const wxSize& pixelSize,
+                        int family,
+                        int style,
+                        int weight,
+                        bool underlined,
+                        const wxString& face,
+                        wxFontEncoding encoding)
+{
+#if defined(__WXMSW__)
+    return new wxFont(pixelSize, family, style, weight, underlined,
+                      face, encoding);
+#else
+    wxFont *self = New(10, family, style, weight, underlined, face, encoding);
+    wxScreenDC dc;
+    AdjustFontSize(*(wxFont *)self, dc, pixelSize);
+    return self;
+#endif
+}
+
+/* static */
+wxFont *wxFontBase::New(const wxSize& pixelSize,
+                        wxFontFamily family,
+                        int flags,
+                        const wxString& face,
+                        wxFontEncoding encoding)
+{
+    return New(pixelSize, family, flags2Style(flags), flags2Weight(flags),
+               flags2Underlined(flags), face, encoding);
+}
+
+wxSize wxFontBase::GetPixelSize() const
+{
+    wxScreenDC dc;
+    dc.SetFont(*(wxFont *)this);
+    return wxSize(dc.GetCharWidth(), dc.GetCharHeight());
+}
+
+bool wxFontBase::IsUsingSizeInPixels() const
+{
+    return false;
+}
+
+void wxFontBase::SetPixelSize( const wxSize& pixelSize )
+{
+    wxScreenDC dc;
+    AdjustFontSize(*(wxFont *)this, dc, pixelSize);
+}
+
 /* static */
 wxFont *wxFontBase::New(const wxNativeFontInfo& info)
 {
@@ -76,26 +235,12 @@ wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
     return New(fontInfo);
 }
 
-wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const
+bool wxFontBase::IsFixedWidth() const
 {
-#ifdef wxNO_NATIVE_FONTINFO
-    wxNativeFontInfo *fontInfo = new wxNativeFontInfo();
-
-    fontInfo->SetPointSize(GetPointSize());
-    fontInfo->SetFamily(GetFamily());
-    fontInfo->SetStyle((wxFontStyle)GetStyle());
-    fontInfo->SetWeight((wxFontWeight)GetWeight());
-    fontInfo->SetUnderlined(GetUnderlined());
-    fontInfo->SetFaceName(GetFaceName());
-    fontInfo->SetEncoding(GetEncoding());
-
-    return fontInfo;
-#else
-    return (wxNativeFontInfo *)NULL;
-#endif
+    return GetFamily() == wxFONTFAMILY_TELETYPE;
 }
 
-void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
+void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
 {
 #ifdef wxNO_NATIVE_FONTINFO
     SetPointSize(info.pointSize);
@@ -113,11 +258,10 @@ void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
 wxString wxFontBase::GetNativeFontInfoDesc() const
 {
     wxString fontDesc;
-    wxNativeFontInfo *fontInfo = GetNativeFontInfo();
+    const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
     if ( fontInfo )
     {
         fontDesc = fontInfo->ToString();
-        delete fontInfo;
     }
 
     return fontDesc;
@@ -126,11 +270,10 @@ wxString wxFontBase::GetNativeFontInfoDesc() const
 wxString wxFontBase::GetNativeFontInfoUserDesc() const
 {
     wxString fontDesc;
-    wxNativeFontInfo *fontInfo = GetNativeFontInfo();
+    const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
     if ( fontInfo )
     {
         fontDesc = fontInfo->ToUserString();
-        delete fontInfo;
     }
 
     return fontDesc;
@@ -250,39 +393,42 @@ bool wxNativeFontInfo::FromString(const wxString& s)
 
     token = tokenizer.GetNextToken();
     if ( !token.ToLong(&l) )
-        return FALSE;
+        return false;
     pointSize = (int)l;
 
     token = tokenizer.GetNextToken();
     if ( !token.ToLong(&l) )
-        return FALSE;
-    family = (int)l;
+        return false;
+    family = (wxFontFamily)l;
 
     token = tokenizer.GetNextToken();
     if ( !token.ToLong(&l) )
-        return FALSE;
+        return false;
     style = (wxFontStyle)l;
 
     token = tokenizer.GetNextToken();
     if ( !token.ToLong(&l) )
-        return FALSE;
+        return false;
     weight = (wxFontWeight)l;
 
     token = tokenizer.GetNextToken();
     if ( !token.ToLong(&l) )
-        return FALSE;
+        return false;
     underlined = l != 0;
 
     faceName = tokenizer.GetNextToken();
+
+#ifndef __WXMAC__
     if( !faceName )
-        return FALSE;
+        return false;
+#endif
 
     token = tokenizer.GetNextToken();
     if ( !token.ToLong(&l) )
-        return FALSE;
+        return false;
     encoding = (wxFontEncoding)l;
 
-    return TRUE;
+    return true;
 }
 
 wxString wxNativeFontInfo::ToString() const
@@ -304,11 +450,11 @@ wxString wxNativeFontInfo::ToString() const
 
 void wxNativeFontInfo::Init()
 {
-    pointSize = wxNORMAL_FONT->GetPointSize();
+    pointSize = 0;
     family = wxFONTFAMILY_DEFAULT;
     style = wxFONTSTYLE_NORMAL;
     weight = wxFONTWEIGHT_NORMAL;
-    underlined = FALSE;
+    underlined = false;
     faceName.clear();
     encoding = wxFONTENCODING_DEFAULT;
 }
@@ -338,6 +484,11 @@ wxString wxNativeFontInfo::GetFaceName() const
     return faceName;
 }
 
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+    return family;
+}
+
 wxFontEncoding wxNativeFontInfo::GetEncoding() const
 {
     return encoding;
@@ -363,9 +514,14 @@ void wxNativeFontInfo::SetUnderlined(bool underlined_)
     underlined = underlined_;
 }
 
-void wxNativeFontInfo::SetFaceName(wxString facename_)
+void wxNativeFontInfo::SetFaceName(const wxString& facename_)
+{
+    faceName = facename_;
+}
+
+void wxNativeFontInfo::SetFamily(wxFontFamily family_)
 {
-    facename = facename_;
+    family = family_;
 }
 
 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
@@ -380,7 +536,7 @@ void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
 // format there anyhow (but there is a well-defined standard for X11 fonts used
 // by wxGTK and wxMotif)
 
-#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__)
+#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
 
 wxString wxNativeFontInfo::ToUserString() const
 {
@@ -423,19 +579,31 @@ wxString wxNativeFontInfo::ToUserString() const
             // we don't distinguish between the two for now anyhow...
         case wxFONTSTYLE_ITALIC:
         case wxFONTSTYLE_SLANT:
-            desc << _("italic ");
+            desc << _("italic");
             break;
     }
 
-    if ( !facename.empty() )
+    wxString face = GetFaceName();
+    if ( !face.empty() )
+    {
+        desc << _T(' ') << face;
+    }
+
+    int size = GetPointSize();
+    if ( size != wxNORMAL_FONT->GetPointSize() )
     {
-        desc << facename << _T(' ');
+        desc << _T(' ') << size;
     }
 
-    if ( pointsize != wxNORMAL_FONT->GetPointSize() )
+#if wxUSE_FONTMAP
+    wxFontEncoding enc = GetEncoding();
+    if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
     {
-        desc << pointsize;
+        desc << _T(' ') << wxFontMapper::GetEncodingName(enc);
     }
+#endif // wxUSE_FONTMAP
+
+    return desc;
 }
 
 bool wxNativeFontInfo::FromUserString(const wxString& s)
@@ -450,19 +618,22 @@ bool wxNativeFontInfo::FromUserString(const wxString& s)
 
     wxString face;
     unsigned long size;
+
+#if wxUSE_FONTMAP
     wxFontEncoding encoding;
+#endif // wxUSE_FONTMAP
 
     while ( tokenizer.HasMoreTokens() )
     {
         wxString token = tokenizer.GetNextToken();
 
         // normalize it
-        token.Trim(TRUE).Trim(FALSE).MakeLower();
+        token.Trim(true).Trim(false).MakeLower();
 
         // look for the known tokens
         if ( token == _T("underlined") || token == _("underlined") )
         {
-            SetUnderlined(TRUE);
+            SetUnderlined(true);
         }
         else if ( token == _T("light") || token == _("light") )
         {
@@ -478,13 +649,15 @@ bool wxNativeFontInfo::FromUserString(const wxString& s)
         }
         else if ( token.ToULong(&size) )
         {
-            pointsize = (int)size;
+            SetPointSize(size);
         }
-        else if ( (encoding = wxTheFontMapper->CharsetToEncoding(token, FALSE))
+#if wxUSE_FONTMAP
+        else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, false))
                     != wxFONTENCODING_DEFAULT )
         {
             SetEncoding(encoding);
         }
+#endif // wxUSE_FONTMAP
         else // assume it is the face name
         {
             if ( !face.empty() )
@@ -514,8 +687,8 @@ bool wxNativeFontInfo::FromUserString(const wxString& s)
         SetFaceName(face);
     }
 
-    return TRUE;
+    return true;
 }
 
-#endif // generic or wxMSW
+#endif // generic or wxMSW or wxOS2