2 * @file OptionsFont.cpp
4 * @brief Implementation for Options::Font class.
7 #include "OptionsFont.h"
9 #include "ExConverter.h"
10 #include "OptionsDef.h"
11 #include "OptionsMgr.h"
14 namespace Options { namespace Font {
17 * @brief Initialize basic default values in a LOGFONT structure.
18 * A helper function for SetDefaults(); it should not be used otherwise.
20 void InitializeLogFont(LOGFONT &logfont, int lfHeight, int lfCharSet, int lfPitchAndFamily, String lfFaceName)
22 logfont.lfHeight = lfHeight;
24 logfont.lfEscapement = 0;
25 logfont.lfOrientation = 0;
26 logfont.lfWeight = FW_NORMAL;
27 logfont.lfItalic = false;
28 logfont.lfUnderline = false;
29 logfont.lfStrikeOut = false;
30 logfont.lfCharSet = static_cast<BYTE>(lfCharSet);
31 logfont.lfOutPrecision = OUT_STRING_PRECIS;
32 logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
33 logfont.lfQuality = DRAFT_QUALITY;
34 logfont.lfPitchAndFamily = static_cast<BYTE>(lfPitchAndFamily);
35 lstrcpyn(logfont.lfFaceName, lfFaceName.c_str(), (sizeof(logfont.lfFaceName)/sizeof(logfont.lfFaceName[0])) );
39 * @brief Initialize the in-memory Options::Font structure (and possibly the related Registry entries)
40 * for both File-Contents and Directory-Tree windows.
42 void SetDefaults(COptionsMgr *pOptionsMgr)
44 HDC hDC = GetDC(nullptr);
45 const int logPixelsY = GetDeviceCaps(hDC, LOGPIXELSY);
48 // File-Contents windows use fixed-width fonts. Here we discover the
49 // correct default fontname from the system code page, if possible. The
50 // default size is 12 points. If a fontname cannot be found (why?),
51 // "Courier New" will be used for the fontname.
52 LOGFONT fontFile = {0};
53 const int pointsFile = 12;
55 CodePageInfo cpi = {0};
56 IExconverter *pexconv = Exconverter::getInstance();
57 if (pexconv==nullptr || !pexconv->getCodePageInfo(GetACP(), &cpi)
58 || cpi.proportionalFont == cpi.fixedWidthFont)
60 cpi.bGDICharset = ANSI_CHARSET;
61 cpi.fixedWidthFont = _T("Courier New");
63 InitializeLogFont(fontFile, -::MulDiv(pointsFile, logPixelsY, 72), cpi.bGDICharset, FF_MODERN | FIXED_PITCH, cpi.fixedWidthFont);
67 // The Directory-Tree window uses (by default) the program's Menu font and size; if
68 // that cannot be determined (why?), 9-point "Segoe UI" is used (typical since Win7).
69 LOGFONT fontDir = {0};
70 const int pointsDir = 9;
71 NONCLIENTMETRICS ncm = { 0 };
72 ncm.cbSize = sizeof(NONCLIENTMETRICS);
73 if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
75 const int lfHeight = -::MulDiv(pointsDir, logPixelsY, 72);
76 fontDir = ncm.lfMenuFont;
77 if (abs(fontDir.lfHeight) > abs(lfHeight))
78 fontDir.lfHeight = lfHeight;
79 if (wcscmp(fontDir.lfFaceName, L"Meiryo") == 0 || wcscmp(fontDir.lfFaceName, L"\U000030e1\U000030a4\U000030ea\U000030aa"/* "Meiryo" in Japanese */) == 0)
80 wcscpy_s(fontDir.lfFaceName, L"Meiryo UI");
84 // in the case of Windows XP
85 InitializeLogFont(fontDir, -::MulDiv(pointsDir, logPixelsY, 72), DEFAULT_CHARSET, FF_DONTCARE, L"Segoe UI");
89 // The values generated above are used as the 'default' Options::Font values. The 'actual' value
90 // for each option is obtained from the Registry, if the entry exists. If the Registry entry
91 // does not exist, it is built using this given 'default' value and the 'actual' value becomes
92 // the same as the 'default'.
93 for (int i = 0; i < 2; ++i)
95 LOGFONT thisFont = (i == 0 ? fontFile : fontDir);
96 String name = (i == 0 ? OPT_FONT_FILECMP : OPT_FONT_DIRCMP);
98 pOptionsMgr->InitOption(name + OPT_FONT_USECUSTOM, false);
99 pOptionsMgr->InitOption(name + OPT_FONT_POINTSIZE, ::MulDiv(abs(thisFont.lfHeight), 72, logPixelsY));
100 pOptionsMgr->InitOption(name + OPT_FONT_HEIGHT, thisFont.lfHeight);
101 pOptionsMgr->InitOption(name + OPT_FONT_ESCAPEMENT, thisFont.lfEscapement);
102 pOptionsMgr->InitOption(name + OPT_FONT_ORIENTATION, thisFont.lfOrientation);
103 pOptionsMgr->InitOption(name + OPT_FONT_WEIGHT, thisFont.lfWeight);
104 pOptionsMgr->InitOption(name + OPT_FONT_ITALIC, thisFont.lfItalic != 0);
105 pOptionsMgr->InitOption(name + OPT_FONT_UNDERLINE, thisFont.lfUnderline != 0);
106 pOptionsMgr->InitOption(name + OPT_FONT_STRIKEOUT, thisFont.lfStrikeOut != 0);
107 pOptionsMgr->InitOption(name + OPT_FONT_CHARSET, thisFont.lfCharSet);
108 pOptionsMgr->InitOption(name + OPT_FONT_OUTPRECISION, thisFont.lfOutPrecision);
109 pOptionsMgr->InitOption(name + OPT_FONT_CLIPPRECISION, thisFont.lfClipPrecision);
110 pOptionsMgr->InitOption(name + OPT_FONT_QUALITY, thisFont.lfQuality);
111 pOptionsMgr->InitOption(name + OPT_FONT_PITCHANDFAMILY, thisFont.lfPitchAndFamily);
112 pOptionsMgr->InitOption(name + OPT_FONT_FACENAME, ucr::toTString(thisFont.lfFaceName));
114 ReleaseDC(nullptr, hDC);
117 LOGFONT Load(const COptionsMgr *pOptionsMgr, const String& name)
119 // Build a new LOGFONT with values from the 'actual' values of the in-memory Options::Font table.
120 // The Registry is not accessed.
121 LOGFONT lfnew = { 0 };
122 HDC hDC = GetDC(nullptr);
123 lfnew.lfHeight = -MulDiv(pOptionsMgr->GetInt(name + OPT_FONT_POINTSIZE), GetDeviceCaps(hDC, LOGPIXELSY), 72);
124 if (lfnew.lfHeight == 0)
125 lfnew.lfHeight = pOptionsMgr->GetInt(name + OPT_FONT_HEIGHT);
127 lfnew.lfEscapement = pOptionsMgr->GetInt(name + OPT_FONT_ESCAPEMENT);
128 lfnew.lfOrientation = pOptionsMgr->GetInt(name + OPT_FONT_ORIENTATION);
129 lfnew.lfWeight = pOptionsMgr->GetInt(name + OPT_FONT_WEIGHT);
130 lfnew.lfItalic = pOptionsMgr->GetBool(name + OPT_FONT_ITALIC);
131 lfnew.lfUnderline = pOptionsMgr->GetBool(name + OPT_FONT_UNDERLINE);
132 lfnew.lfStrikeOut = pOptionsMgr->GetBool(name + OPT_FONT_STRIKEOUT);
133 lfnew.lfCharSet = static_cast<BYTE>(pOptionsMgr->GetInt(name + OPT_FONT_CHARSET));
134 lfnew.lfOutPrecision = static_cast<BYTE>(pOptionsMgr->GetInt(name + OPT_FONT_OUTPRECISION));
135 lfnew.lfClipPrecision = static_cast<BYTE>(pOptionsMgr->GetInt(name + OPT_FONT_CLIPPRECISION));
136 lfnew.lfQuality = static_cast<BYTE>(pOptionsMgr->GetInt(name + OPT_FONT_QUALITY));
137 lfnew.lfPitchAndFamily = static_cast<BYTE>(pOptionsMgr->GetInt(name + OPT_FONT_PITCHANDFAMILY));
138 lstrcpyn(lfnew.lfFaceName,
139 pOptionsMgr->GetString(name + OPT_FONT_FACENAME).c_str(), sizeof(lfnew.lfFaceName)/sizeof(lfnew.lfFaceName[0]));
140 ReleaseDC(nullptr, hDC);
144 void Save(COptionsMgr *pOptionsMgr, const String& name, const LOGFONT* lf, bool bUseCustom)
146 // Store LOGFONT values into both the 'actual' value of the in-memory Options::Font table, and
147 // into the appropriate Registry entries.
148 HDC hDC = GetDC(nullptr);
149 pOptionsMgr->SaveOption(name + OPT_FONT_USECUSTOM, bUseCustom);
150 pOptionsMgr->SaveOption(name + OPT_FONT_POINTSIZE, -MulDiv(lf->lfHeight, 72, GetDeviceCaps(hDC, LOGPIXELSY)));
151 pOptionsMgr->SaveOption(name + OPT_FONT_HEIGHT, lf->lfHeight);
152 pOptionsMgr->SaveOption(name + OPT_FONT_ESCAPEMENT, lf->lfEscapement);
153 pOptionsMgr->SaveOption(name + OPT_FONT_ORIENTATION, lf->lfOrientation);
154 pOptionsMgr->SaveOption(name + OPT_FONT_WEIGHT, lf->lfWeight);
155 pOptionsMgr->SaveOption(name + OPT_FONT_ITALIC, lf->lfItalic != 0);
156 pOptionsMgr->SaveOption(name + OPT_FONT_UNDERLINE, lf->lfUnderline != 0);
157 pOptionsMgr->SaveOption(name + OPT_FONT_STRIKEOUT, lf->lfStrikeOut != 0);
158 pOptionsMgr->SaveOption(name + OPT_FONT_CHARSET, lf->lfCharSet);
159 pOptionsMgr->SaveOption(name + OPT_FONT_OUTPRECISION, lf->lfOutPrecision);
160 pOptionsMgr->SaveOption(name + OPT_FONT_CLIPPRECISION, lf->lfClipPrecision);
161 pOptionsMgr->SaveOption(name + OPT_FONT_QUALITY, lf->lfQuality);
162 pOptionsMgr->SaveOption(name + OPT_FONT_PITCHANDFAMILY, (int)lf->lfPitchAndFamily);
163 pOptionsMgr->SaveOption(name + OPT_FONT_FACENAME, lf->lfFaceName);
164 ReleaseDC(nullptr, hDC);
167 void Reset(COptionsMgr *pOptionsMgr, const String& name)
169 // Resets the in-memory Options::Font 'actual' values to be original 'default' values.
170 // The Registry values are not modified, except to turn off the OPT_FONT_USECUSTOM
172 pOptionsMgr->SaveOption(name + OPT_FONT_USECUSTOM, false);
173 pOptionsMgr->Reset(name + OPT_FONT_POINTSIZE);
174 pOptionsMgr->Reset(name + OPT_FONT_HEIGHT);
175 pOptionsMgr->Reset(name + OPT_FONT_ESCAPEMENT);
176 pOptionsMgr->Reset(name + OPT_FONT_ORIENTATION);
177 pOptionsMgr->Reset(name + OPT_FONT_WEIGHT);
178 pOptionsMgr->Reset(name + OPT_FONT_ITALIC);
179 pOptionsMgr->Reset(name + OPT_FONT_UNDERLINE);
180 pOptionsMgr->Reset(name + OPT_FONT_STRIKEOUT);
181 pOptionsMgr->Reset(name + OPT_FONT_CHARSET);
182 pOptionsMgr->Reset(name + OPT_FONT_OUTPRECISION);
183 pOptionsMgr->Reset(name + OPT_FONT_CLIPPRECISION);
184 pOptionsMgr->Reset(name + OPT_FONT_QUALITY);
185 pOptionsMgr->Reset(name + OPT_FONT_PITCHANDFAMILY);
186 pOptionsMgr->Reset(name + OPT_FONT_FACENAME);