soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SFontPool.cpp
1//////////////////////////////////////////////////////////////////////////
2// Class Name: SFontPool
3// Description: Font Pool
4//////////////////////////////////////////////////////////////////////////
5#include "souistd.h"
6#include "res.mgr/SFontPool.h"
7#include "helper/SplitString.h"
8#include "layout/SLayoutSize.h"
9#include "helper/SHostMgr.h"
10
11SNSBEGIN
12
13int CALLBACK DefFontsEnumProc(CONST LOGFONT *lplf, // logical-font data
14 CONST TEXTMETRIC *lptm, // physical-font data
15 DWORD dwType, // font type
16 LPARAM lpData // application-defined data
17)
18{
19 BOOL *pbValidFont = (BOOL *)lpData;
20 *pbValidFont = TRUE;
21 return 0; // stop enum.
22}
23
24static BOOL DefFontCheck(const SStringW &strFontName)
25{
26 return HasFont(S_CW2T(strFontName));
27}
28
29FunFontCheck SFontPool::s_funFontCheck = DefFontCheck;
30
31void SFontPool::SetFontChecker(FunFontCheck fontCheck)
32{
33 s_funFontCheck = fontCheck;
34}
35
36BOOL SFontPool::CheckFont(const SStringW &strFontName)
37{
38 return s_funFontCheck(strFontName);
39}
40
42 : m_RenderFactory(fac)
43{
45 FontInfo emptyInfo;
46 m_defFontInfo = FontInfoFromString(L"face:宋体,size:16", emptyInfo);
47}
48
53
54void SFontPool::OnKeyRemoved(const IFontPtr &obj)
55{
56 obj->Release();
57}
58
59static const WCHAR KFontPropSeprator = L','; //字体属性之间的分隔符,不再支持其它符号。
60static const WCHAR KPropSeprator = L':'; //一个属性name:value对之间的分隔符
61static const WCHAR kExPropKey[] = L"exprop";
62static const WCHAR KFontFace[] = L"face";
63static const WCHAR KFontBold[] = L"bold";
64static const WCHAR KFontUnderline[] = L"underline";
65static const WCHAR KFontItalic[] = L"italic";
66static const WCHAR KFontStrike[] = L"strike";
67static const WCHAR KFontAdding[] = L"adding";
68static const WCHAR KFontSize[] = L"size";
69static const WCHAR KFontCharset[] = L"charset";
70static const WCHAR KFontWeight[] = L"weight";
71static const WCHAR KFontEscapement[] = L"escapement";
72const static WCHAR KDefFontFace[] = L"宋体";
73
74IFontPtr SFontPool::_GetFont(const SStringW &strFont, int scale)
75{
76 SStringW strFontDesc = GETUIDEF->GetFontDesc(strFont);
77 FontInfo info = FontInfoFromString(strFontDesc, m_defFontInfo);
78 info.scale = scale;
79 IFontPtr hftRet = NULL;
80 if (HasKey(info))
81 {
82 hftRet = GetKeyObject(info);
83 }
84 else
85 {
86 hftRet = _CreateFont(info);
87 AddKeyObject(info, hftRet);
88 }
89 return hftRet;
90}
91
92IFontPtr SFontPool::_CreateFont(const FontInfo &fontInfo)
93{
94 LOGFONT lfNew = { 0 };
95
96 lfNew.lfCharSet = fontInfo.style.attr.byCharset;
97
98 //优先使用weigth属性.
99 lfNew.lfWeight = (long)(fontInfo.style.attr.byWeight * 4);
100 if (lfNew.lfWeight == 0) //没有weight属性时检查bold属性.
101 lfNew.lfWeight = (fontInfo.style.attr.fBold ? FW_BOLD : FW_NORMAL);
102 lfNew.lfUnderline = (FALSE != fontInfo.style.attr.fUnderline);
103 lfNew.lfItalic = (FALSE != fontInfo.style.attr.fItalic);
104 lfNew.lfStrikeOut = (FALSE != fontInfo.style.attr.fStrike);
105 lfNew.lfEscapement = lfNew.lfOrientation = fontInfo.style.attr.fEscapement;
106 if (fontInfo.style.attr.szIsAdding)
107 {
108 SLayoutSize defFontSize((float)(short)m_defFontInfo.style.attr.nSize, (SLayoutSize::Unit)m_defFontInfo.style.attr.szUnit);
109 lfNew.lfHeight = -defFontSize.toPixelSize(fontInfo.scale);
110 SLayoutSize layoutSize((float)(short)fontInfo.style.attr.nSize, (SLayoutSize::Unit)fontInfo.style.attr.szUnit);
111 lfNew.lfHeight -= layoutSize.toPixelSize(fontInfo.scale);
112 }
113 else
114 {
115 SLayoutSize layoutSize((float)(int)fontInfo.style.attr.nSize, (SLayoutSize::Unit)fontInfo.style.attr.szUnit);
116 lfNew.lfHeight = -layoutSize.toPixelSize(fontInfo.scale);
117 }
118 lfNew.lfQuality = CLEARTYPE_QUALITY;
119
120 _tcscpy_s(lfNew.lfFaceName, _countof(lfNew.lfFaceName), S_CW2T(fontInfo.strFaceName));
121 IFontPtr ret = NULL;
122 SASSERT(m_RenderFactory);
123 m_RenderFactory->CreateFont(&ret, &lfNew);
124
125 if (!fontInfo.strPropEx.IsEmpty())
126 {
127 SXmlDoc xmlDoc;
128 xmlDoc.load_string(fontInfo.strPropEx.c_str());
129 SXmlNode xmlExProp = xmlDoc.root().child(kExPropKey);
130 ret->SetProp(&xmlExProp);
131 }
132 return ret;
133}
134
136{
137 return m_defFontInfo;
138}
139
141{
142 m_defFontInfo = fontInfo;
143 RemoveAll();
145}
146
147void SFontPool::_SetDefFontInfo(const SStringW &strFontInfo)
148{
149 if (strFontInfo.IsEmpty())
150 return;
151 FontInfo emptyDefFont;
152 emptyDefFont.scale = 100;
153 FontInfo fi = FontInfoFromString(strFontInfo, emptyDefFont);
154 if (!CheckFont(fi.strFaceName))
155 { // make sure default font face is valid.
156 fi.strFaceName = KDefFontFace;
157 }
158 _SetDefFontInfo(fi);
159}
160
161FontInfo SFontPool::FontInfoFromString(const SStringW &strFontDesc, const FontInfo &defFontInfo)
162{
163 FontInfo fi = defFontInfo;
164 SXmlDoc xmlExProp;
165 SXmlNode nodeExp;
166 if (fi.strPropEx.IsEmpty())
167 nodeExp = xmlExProp.root().append_child(kExPropKey);
168 else
169 {
170 xmlExProp.load_string(fi.strPropEx.c_str());
171 nodeExp = xmlExProp.root().child(kExPropKey);
172 }
173 SStringW fontDesc2 = strFontDesc;
174 SArray<SStringW> strLst;
175 size_t nSeg = SplitString(fontDesc2, KFontPropSeprator, strLst);
176 for (size_t i = 0; i < nSeg; i++)
177 {
178 SArray<SStringW> kv;
179 size_t n = SplitString(strLst[i], KPropSeprator, kv);
180 if (n != 2)
181 continue;
182 kv[0].MakeLower();
183 if (kv[0] == KFontFace)
184 {
185 if (kv[1][0] == L'\'' || kv[1][0] == L'\"')
186 fi.strFaceName = kv[1].Mid(1, kv[1].GetLength() - 2);
187 else
188 fi.strFaceName = kv[1];
189 }
190 else if (kv[0] == KFontSize)
191 {
192 SLayoutSize layoutSize;
193 layoutSize.parseString(kv[1]);
194 fi.style.attr.nSize = (short)abs(layoutSize.fSize);
195 fi.style.attr.szUnit = (int)layoutSize.unit;
196 fi.style.attr.szIsAdding = 0;
197 }
198 else if (kv[0] == KFontAdding)
199 {
200 SLayoutSize layoutSize;
201 layoutSize.parseString(kv[1]);
202 fi.style.attr.nSize = (short)layoutSize.fSize;
203 fi.style.attr.szUnit = (int)layoutSize.unit;
204 fi.style.attr.szIsAdding = 1;
205 }
206 else if (kv[0] == KFontCharset)
207 {
208 fi.style.attr.byCharset = _wtoi(kv[1]);
209 }
210 else if (kv[0] == KFontWeight)
211 {
212 fi.style.attr.byWeight = (_wtoi(kv[1]) + 2) / 4; //+2 for 四舍五入. /4是为了把weight scale到0-250.
213 }
214 else if (kv[0] == KFontBold)
215 {
216 fi.style.attr.fBold = _wtoi(kv[1]);
217 }
218 else if (kv[0] == KFontItalic)
219 {
220 fi.style.attr.fItalic = _wtoi(kv[1]);
221 }
222 else if (kv[0] == KFontStrike)
223 {
224 fi.style.attr.fStrike = _wtoi(kv[1]);
225 }
226 else if (kv[0] == KFontUnderline)
227 {
228 fi.style.attr.fUnderline = _wtoi(kv[1]);
229 }
230 else if (kv[0] == KFontEscapement)
231 {
232 int fescapement = (int)(_wtof(kv[1]) * 10);
233 fescapement %= 3600;
234 if (fescapement < 0)
235 fescapement += 3600;
236 // make sure fescapement is between [0,3600)
237 fi.style.attr.fEscapement = fescapement;
238 }
239 else
240 { // extend props
241 nodeExp.append_attribute(kv[0].c_str()).set_value(kv[1].c_str());
242 }
243 }
244 if (nodeExp.first_attribute())
245 {
246 nodeExp.ToString(&fi.strPropEx);
247 }
248 return fi;
249}
250
252{
253 char szBuf[200];
254 SLogStream s(szBuf, 200);
255 s << KFontFace << KPropSeprator << "\'" << fi.strFaceName.c_str() << "\'"
256 << ",";
257 s << KFontSize << KPropSeprator << (short)fi.style.attr.nSize << ",";
258 s << KFontCharset << KPropSeprator << fi.style.attr.byCharset << ",";
259 s << KFontWeight << KPropSeprator << fi.style.attr.byWeight * 4 << ",";
260 s << KFontBold << KPropSeprator << (fi.style.attr.fBold ? "1" : "0") << ",";
261 s << KFontItalic << KPropSeprator << (fi.style.attr.fItalic ? "1" : "0") << ",";
262 s << KFontStrike << KPropSeprator << (fi.style.attr.fStrike ? "1" : "0") << ",";
263 s << KFontUnderline << KPropSeprator << (fi.style.attr.fUnderline ? "1" : "0");
264 s << KFontEscapement << KPropSeprator << fi.style.attr.fEscapement;
265
266 return S_CA2W(szBuf);
267}
268
269IFontPtr SFontPool::GetFont(const SStringW &strFont, int scale)
270{
271 return GETUIDEF->GetFont(strFont, scale);
272}
273
274void SFontPool::SetDefFontInfo(const SStringW &strFontInfo)
275{
276 return GETUIDEF->SetDefFontInfo(strFontInfo);
277}
278
280{
281 return GETUIDEF->GetDefFontInfo();
282}
283
284SNSEND
SOUI Font Management Module.
bool GetKeyObject(const FontInfo &key, IFontPtr &obj) const
Definition SCmnMap.h:65
bool AddKeyObject(const FontInfo &key, const IFontPtr &obj)
Definition SCmnMap.h:94
bool HasKey(const FontInfo &key) const
Definition SCmnMap.h:52
void(* m_pFunOnKeyRemoved)(const IFontPtr &obj)
Definition SCmnMap.h:167
static FunFontCheck s_funFontCheck
Definition SFontPool.h:202
const FontInfo & _GetDefFontInfo() const
Get constant reference to default font information.
FontInfo m_defFontInfo
Definition SFontPool.h:200
static FontInfo FontInfoFromString(const SStringW &strFontInfo, const FontInfo &defFontInfo)
Convert font description to FontInfo.
static void OnKeyRemoved(const IFontPtr &obj)
Callback function when FontInfo is removed.
Definition SFontPool.cpp:54
static void SetFontChecker(FunFontCheck fontCheck)
Set the callback function for checking fonts.
Definition SFontPool.cpp:31
SAutoRefPtr< IRenderFactory > m_RenderFactory
Definition SFontPool.h:199
SFontPool(IRenderFactory *fac)
Constructor.
Definition SFontPool.cpp:41
void SetRenderFactory(IRenderFactory *fac)
Set render factory object.
Definition SFontPool.cpp:49
static BOOL CheckFont(const SStringW &strFontName)
Check if a font is valid.
Definition SFontPool.cpp:36
static IFontPtr GetFont(const SStringW &strFont, int scale)
Get IFontPtr corresponding to the specified description string.
IFontPtr _GetFont(const SStringW &strFont, int scale)
Get IFontPtr corresponding to the specified description string.
Definition SFontPool.cpp:74
void _SetDefFontInfo(const SStringW &strFontInfo)
Set default font description string.
static SStringW FontInfoToString(const FontInfo &fi)
Convert FontInfo to font description.
IFontPtr _CreateFont(const FontInfo &fontInfo)
Create font object corresponding to FontInfo.
Definition SFontPool.cpp:92
static void SetDefFontInfo(const SStringW &strFontInfo)
Set default font.
static FontInfo GetDefFontInfo()
Get default font information.
void DispatchMessage(UINT uMsg, WPARAM wp=0, LPARAM lp=0)
分发消息到宿主窗口
Definition SHostMgr.cpp:28
布局大小类
Definition SLayoutSize.h:10
void parseString(const SStringW &strSize)
从字符串解析大小
int toPixelSize(int scale) const
将大小转换为像素值
Unit
布局大小单位枚举
Definition SLayoutSize.h:17
日志流类,用于格式化日志输出
Definition slog.h:48
static SHostMgr * getSingletonPtr(void)
Definition SSingleton2.h:70
A class representing an ASCII string.
Definition sstringw.h:96
const wchar_t * c_str() SCONST
Retrieves a C-style string representation of the string.
BOOL IsEmpty() SCONST
Checks if the string is empty.
SStringW Mid(int nFirst) const
Extracts a substring from the string.
Definition sstringw.cpp:924
bool set_value(const wchar_t *rhs)
Sets the attribute value.
Definition SXml.cpp:130
Implementation of IXmlDoc.
Definition SXml.h:912
SXmlNode root() const
Retrieves the root node of the document.
Definition SXml.cpp:754
bool load_string(const wchar_t *contents, unsigned int options=xml_parse_default)
Loads the document from a zero-terminated string.
Definition SXml.cpp:708
Class representing an XML node.
Definition SXml.h:352
SXmlAttr first_attribute() const
Gets the first attribute of the node.
Definition SXml.cpp:373
void ToString(IStringW *out) SCONST OVERRIDE
Converts the node to a string representation.
Definition SXml.cpp:238
SXmlAttr append_attribute(const wchar_t *name)
Adds an attribute with the specified name.
Definition SXml.cpp:458
SXmlNode child(const wchar_t *name, bool bCaseSensitive=false) const
Gets the child node, attribute, or next/previous sibling with the specified name.
Definition SXml.cpp:423
SXmlNode append_child(XmlNodeType type=node_element)
Adds a child node with the specified type.
Definition SXml.cpp:518
Font information structure.
Definition SFontInfo.h:51
int scale
Definition SFontInfo.h:55
SStringW strFaceName
Definition SFontInfo.h:53
FONTSTYLE style
Definition SFontInfo.h:52
SStringW strPropEx
Definition SFontInfo.h:54
void SetProp(IXmlNode *pXmlNode) PURE
Sets properties from an XML node.
long Release() PURE
Decrements the reference count for the object.
RenderFactory object.
Definition SRender-i.h:2018
uint64_t fUnderline
Definition SFontInfo.h:24
uint64_t fItalic
Definition SFontInfo.h:23
uint64_t fEscapement
Definition SFontInfo.h:27
uint64_t byCharset
Definition SFontInfo.h:21
uint64_t fBold
Definition SFontInfo.h:25
uint64_t szUnit
Definition SFontInfo.h:30
uint64_t fStrike
Definition SFontInfo.h:26
uint64_t byWeight
Definition SFontInfo.h:22
uint64_t nSize
Definition SFontInfo.h:31
uint64_t szIsAdding
Definition SFontInfo.h:29