• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include <wx/defs.h>
28 #include <wx/gdicmn.h>
29 #include "fontprops.h"
30 #include "math.h"
31 #include "MathExtras.h"
32 
33 #include <wx/wx.h>
34 #include "wx/msw/private.h"
35 
my_round(double x)36 inline long  my_round(double x)
37 {
38     return (long)(x < 0 ? x - 0.5 : x + 0.5);
39 }
40 
wxFontProperties(wxFont * font)41 wxFontProperties::wxFontProperties(wxFont* font):
42 m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
43 {
44     HDC dc = GetDC(0);
45     WXHFONT hFont = font->GetHFONT();
46     ::SelectObject(dc, hFont);
47     if (font){
48 
49         int height = font->GetPointSize();
50 
51         TEXTMETRIC tm;
52         GetTextMetrics(dc, &tm);
53         m_ascent = lroundf(tm.tmAscent);
54         m_descent = lroundf(tm.tmDescent);
55         m_xHeight = m_ascent * 0.56f;  // Best guess for xHeight for non-Truetype fonts.
56         m_lineGap = lroundf(tm.tmExternalLeading);
57         m_lineSpacing = m_lineGap + m_ascent + m_descent;
58     }
59     RestoreDC(dc, -1);
60     ReleaseDC(0, dc);
61 }
62 
GetTextExtent(const wxFont & font,const wxString & str,wxCoord * width,wxCoord * height,wxCoord * descent,wxCoord * externalLeading)63 void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height,
64                             wxCoord *descent, wxCoord *externalLeading )
65 {
66     HDC dc = GetDC(0);
67     WXHFONT hFont = font.GetHFONT();
68     ::SelectObject(dc, hFont);
69 
70     HFONT hfontOld;
71     if ( font != wxNullFont )
72     {
73         wxASSERT_MSG( font.Ok(), _T("invalid font in wxDC::GetTextExtent") );
74 
75         hfontOld = (HFONT)::SelectObject(dc, hFont);
76     }
77     else // don't change the font
78     {
79         hfontOld = 0;
80     }
81 
82     SIZE sizeRect;
83     const size_t len = str.length();
84     if ( !::GetTextExtentPoint32(dc, str, len, &sizeRect) )
85     {
86         wxLogLastError(_T("GetTextExtentPoint32()"));
87     }
88 
89 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
90     // the result computed by GetTextExtentPoint32() may be too small as it
91     // accounts for under/overhang of the first/last character while we want
92     // just the bounding rect for this string so adjust the width as needed
93     // (using API not available in 2002 SDKs of WinCE)
94     if ( len > 1 )
95     {
96         ABC width;
97         const wxChar chFirst = *str.begin();
98         if ( ::GetCharABCWidths(dc, chFirst, chFirst, &width) )
99         {
100             if ( width.abcA < 0 )
101                 sizeRect.cx -= width.abcA;
102 
103             if ( len > 1 )
104             {
105                 const wxChar chLast = *str.rbegin();
106                 ::GetCharABCWidths(dc, chLast, chLast, &width);
107             }
108             //else: we already have the width of the last character
109 
110             if ( width.abcC < 0 )
111                 sizeRect.cx -= width.abcC;
112         }
113         //else: GetCharABCWidths() failed, not a TrueType font?
114     }
115 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
116 
117     TEXTMETRIC tm;
118     ::GetTextMetrics(dc, &tm);
119 
120     if (width)
121         *width = sizeRect.cx;
122     if (height)
123         *height = sizeRect.cy;
124     if (descent)
125         *descent = tm.tmDescent;
126     if (externalLeading)
127         *externalLeading = tm.tmExternalLeading;
128 
129     if ( hfontOld )
130     {
131         ::SelectObject(dc, hfontOld);
132     }
133 
134     ReleaseDC(0, dc);
135 }
136