]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fontcmn.cpp
small optimization in wxConfigPathChanger: don't change the path if it is already...
[wxWidgets.git] / src / common / fontcmn.cpp
index 7a5e05ca0c934e133d9436158231666e74a5e170..c4416f5bec3301a82f9c768b6773a6c5dbd90bb2 100644 (file)
@@ -29,8 +29,9 @@
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/font.h"
-#include "wx/intl.h"
+    #include "wx/font.h"
+    #include "wx/intl.h"
+    #include "wx/dcscreen.h"
 #endif // WX_PRECOMP
 
 #include "wx/gdicmn.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
 // ----------------------------------------------------------------------------
@@ -83,31 +139,87 @@ wxFont *wxFontBase::New(int size,
     return new wxFont(size, family, style, weight, underlined, face, encoding);
 }
 
-/* static */
-wxFont *wxFontBase::New(int pointSize,
-                        wxFontFamily family,
-                        int flags,
-                        const wxString& face,
-                        wxFontEncoding encoding)
+static inline int flags2Style(int flags)
 {
-    return New
-           (
-                pointSize,
-                family,
-                flags & wxFONTFLAG_ITALIC
+    return flags & wxFONTFLAG_ITALIC
                     ? wxFONTSTYLE_ITALIC
                     : flags & wxFONTFLAG_SLANT
                         ? wxFONTSTYLE_SLANT
-                        : wxFONTSTYLE_NORMAL,
-                flags & wxFONTFLAG_LIGHT
+                        : wxFONTSTYLE_NORMAL;
+}
+
+static inline int flags2Weight(int flags)
+{
+    return flags & wxFONTFLAG_LIGHT
                     ? wxFONTWEIGHT_LIGHT
                     : flags & wxFONTFLAG_BOLD
                         ? wxFONTWEIGHT_BOLD
-                        : wxFONTWEIGHT_NORMAL,
-                (flags & wxFONTFLAG_UNDERLINED) != 0,
-                face,
-                encoding
-           );
+                        : 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 */