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