]> git.saurik.com Git - wxWidgets.git/blame - src/msw/fontdlg.cpp
corrected a crash in wxDialog::Show() which would happen if there was a
[wxWidgets.git] / src / msw / fontdlg.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: fontdlg.cpp
3// Purpose: wxFontDialog class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "fontdlg.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <stdio.h>
25#include "wx/defs.h"
26#include "wx/utils.h"
27#include "wx/dialog.h"
28#endif
29
30#include "wx/fontdlg.h"
31
32#include <windows.h>
33
34#ifndef __WIN32__
35#include <commdlg.h>
36#endif
37
38#include "wx/msw/private.h"
39#include "wx/cmndata.h"
40
41#include <math.h>
42#include <stdlib.h>
43#include <string.h>
44
45#define wxDIALOG_DEFAULT_X 300
46#define wxDIALOG_DEFAULT_Y 300
47
48#if !USE_SHARED_LIBRARY
49IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
50#endif
51
52/*
53 * wxFontDialog
54 */
55
56
57wxFontDialog::wxFontDialog(void)
58{
bbcdf8bc 59 m_dialogParent = NULL;
2bda0e17
KB
60}
61
62wxFontDialog::wxFontDialog(wxWindow *parent, wxFontData *data)
63{
64 Create(parent, data);
65}
66
67bool wxFontDialog::Create(wxWindow *parent, wxFontData *data)
68{
bbcdf8bc
JS
69 m_dialogParent = parent;
70
2bda0e17 71 if (data)
bbcdf8bc 72 m_fontData = *data;
2bda0e17
KB
73 return TRUE;
74}
75
76int wxFontDialog::ShowModal(void)
77{
78 CHOOSEFONT chooseFontStruct;
79 LOGFONT logFont;
80
81 DWORD flags = CF_TTONLY | CF_SCREENFONTS | CF_NOSIMULATIONS;
82
83 memset(&chooseFontStruct, 0, sizeof(CHOOSEFONT));
84
85 chooseFontStruct.lStructSize = sizeof(CHOOSEFONT);
bbcdf8bc 86 chooseFontStruct.hwndOwner = (HWND) (m_dialogParent ? (HWND) m_dialogParent->GetHWND() : NULL);
2bda0e17
KB
87 chooseFontStruct.lpLogFont = &logFont;
88
bbcdf8bc 89 if (m_fontData.initialFont.Ok())
2bda0e17
KB
90 {
91 flags |= CF_INITTOLOGFONTSTRUCT;
bbcdf8bc 92 wxFillLogFont(&logFont, & m_fontData.initialFont);
2bda0e17
KB
93 }
94
95 chooseFontStruct.iPointSize = 0;
bbcdf8bc 96 chooseFontStruct.rgbColors = RGB((BYTE)m_fontData.fontColour.Red(), (BYTE)m_fontData.fontColour.Green(), (BYTE)m_fontData.fontColour.Blue());
2bda0e17 97
bbcdf8bc 98 if (!m_fontData.GetAllowSymbols())
2bda0e17 99 flags |= CF_ANSIONLY;
bbcdf8bc 100 if (m_fontData.GetEnableEffects())
2bda0e17 101 flags |= CF_EFFECTS;
bbcdf8bc 102 if (m_fontData.GetShowHelp())
2bda0e17 103 flags |= CF_SHOWHELP;
bbcdf8bc 104 if (!(m_fontData.minSize == 0 && m_fontData.maxSize == 0))
2bda0e17 105 {
bbcdf8bc
JS
106 chooseFontStruct.nSizeMin = m_fontData.minSize;
107 chooseFontStruct.nSizeMax = m_fontData.maxSize;
2bda0e17
KB
108 flags |= CF_LIMITSIZE;
109 }
110
111 chooseFontStruct.Flags = flags;
112 chooseFontStruct.nFontType = SCREEN_FONTTYPE;
113 bool success = (ChooseFont(&(chooseFontStruct)) != 0);
114
115 // Restore values
116 if (success)
117 {
bbcdf8bc 118 m_fontData.fontColour.Set(GetRValue(chooseFontStruct.rgbColors), GetGValue(chooseFontStruct.rgbColors),
2bda0e17 119 GetBValue(chooseFontStruct.rgbColors));
bbcdf8bc 120 m_fontData.chosenFont = wxCreateFontFromLogFont(&logFont);
2bda0e17
KB
121 }
122
123 return success ? wxID_OK : wxID_CANCEL;
124}
125
126void wxFillLogFont(LOGFONT *logFont, wxFont *font)
127{
128 BYTE ff_italic;
129 int ff_weight = 0;
130 int ff_family = 0;
131 wxString ff_face("");
132
133 switch (font->GetFamily())
134 {
135 case wxSCRIPT: ff_family = FF_SCRIPT ;
136 ff_face = "Script" ;
137 break ;
138 case wxDECORATIVE: ff_family = FF_DECORATIVE;
139 break;
140 case wxROMAN: ff_family = FF_ROMAN;
141 ff_face = "Times New Roman" ;
142 break;
143 case wxTELETYPE:
144 case wxMODERN: ff_family = FF_MODERN;
145 ff_face = "Courier New" ;
146 break;
147 case wxSWISS: ff_family = FF_SWISS;
148 ff_face = "Arial";
149 break;
150 case wxDEFAULT:
151 default: ff_family = FF_SWISS;
152 ff_face = "MS Sans Serif" ;
153 }
154
155 if (font->GetStyle() == wxITALIC || font->GetStyle() == wxSLANT)
156 ff_italic = 1;
157 else
158 ff_italic = 0;
159
160 if (font->GetWeight() == wxNORMAL)
161 ff_weight = FW_NORMAL;
162 else if (font->GetWeight() == wxLIGHT)
163 ff_weight = FW_LIGHT;
164 else if (font->GetWeight() == wxBOLD)
165 ff_weight = FW_BOLD;
166
167 // Have to get screen DC Caps, because a metafile will return 0.
168 HDC dc2 = ::GetDC(NULL);
169 int ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
170 ::ReleaseDC(NULL, dc2);
171
172 // New behaviour: apparently ppInch varies according to
173 // Large/Small Fonts setting in Windows. This messes
174 // up fonts. So, set ppInch to a constant 96 dpi.
175 ppInch = 96;
176
177#if FONT_SIZE_COMPATIBILITY
178 // Incorrect, but compatible with old wxWindows behaviour
179 int nHeight = (font->GetPointSize()*ppInch/72);
180#else
181 // Correct for Windows compatibility
182 int nHeight = - (font->GetPointSize()*ppInch/72);
183#endif
184
185 bool ff_underline = font->GetUnderlined();
186
187 ff_face = font->GetFaceName();
188
189 logFont->lfHeight = nHeight;
190 logFont->lfWidth = 0;
191 logFont->lfEscapement = 0;
192 logFont->lfOrientation = 0;
193 logFont->lfWeight = ff_weight;
194 logFont->lfItalic = ff_italic;
195 logFont->lfUnderline = (BYTE)ff_underline;
196 logFont->lfStrikeOut = 0;
197 logFont->lfCharSet = ANSI_CHARSET;
198 logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
199 logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
200 logFont->lfQuality = PROOF_QUALITY;
201 logFont->lfPitchAndFamily = DEFAULT_PITCH | ff_family;
202 strcpy(logFont->lfFaceName, ff_face);
203}
204
205wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew)
206{
207 int fontFamily = wxSWISS;
208 int fontStyle = wxNORMAL;
209 int fontWeight = wxNORMAL;
210 int fontPoints = 10;
211 bool fontUnderline = FALSE;
212 char *fontFace = NULL;
213
214// int lfFamily = logFont->lfPitchAndFamily & 0xF0;
215 int lfFamily = logFont->lfPitchAndFamily;
216 if (lfFamily & FIXED_PITCH)
217 lfFamily -= FIXED_PITCH;
218 if (lfFamily & VARIABLE_PITCH)
219 lfFamily -= VARIABLE_PITCH;
220
221 switch (lfFamily)
222 {
223 case FF_ROMAN:
224 fontFamily = wxROMAN;
225 break;
226 case FF_SWISS:
227 fontFamily = wxSWISS;
228 break;
229 case FF_SCRIPT:
230 fontFamily = wxSCRIPT;
231 break;
232 case FF_MODERN:
233 fontFamily = wxMODERN;
234 break;
235 case FF_DECORATIVE:
236 fontFamily = wxDECORATIVE;
237 break;
238 default:
239 fontFamily = wxSWISS;
240 break;
241 }
242 switch (logFont->lfWeight)
243 {
244 case FW_LIGHT:
245 fontWeight = wxLIGHT;
246 break;
247 case FW_NORMAL:
248 fontWeight = wxNORMAL;
249 break;
250 case FW_BOLD:
251 fontWeight = wxBOLD;
252 break;
253 default:
254 fontWeight = wxNORMAL;
255 break;
256 }
257 if (logFont->lfItalic)
258 fontStyle = wxITALIC;
259 else
260 fontStyle = wxNORMAL;
261
262 if (logFont->lfUnderline)
263 fontUnderline = TRUE;
264
265 if (logFont->lfFaceName)
266 fontFace = logFont->lfFaceName;
267
268 HDC dc2 = ::GetDC(NULL);
269
270 if ( logFont->lfHeight < 0 )
271 logFont->lfHeight = - logFont->lfHeight;
272 fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY));
273 ::ReleaseDC(NULL, dc2);
274
275// if ( createNew )
276 return wxFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
277// else
278// return wxTheFontList->FindOrCreateFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
279}
280
281