1 /*
2   KeePass Password Safe - The Open-Source Password Manager
3   Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.Diagnostics;
23 using System.Drawing;
24 using System.IO;
25 using System.Text;
26 using System.Xml;
27 
28 using KeePass.Util;
29 
30 using KeePassLib.Native;
31 using KeePassLib.Utility;
32 
33 namespace KeePass.UI
34 {
35 	public static class UISystemFonts
36 	{
37 		private static bool m_bInitialized = false;
38 
39 		private static Font m_fontUI = null;
40 		public static Font DefaultFont
41 		{
42 			get { EnsureInitialized(); return m_fontUI; }
43 		}
44 
45 		private static Font m_fontList = null;
46 		public static Font ListFont
47 		{
48 			get { EnsureInitialized(); return m_fontList; }
49 		}
50 
51 		internal static bool OverrideUIFont
52 		{
53 			get
54 			{
55 				return (NativeLib.IsUnix() && Program.Config.UI.ForceSystemFontUnix);
56 			}
57 		}
58 
EnsureInitialized()59 		private static void EnsureInitialized()
60 		{
61 			if(m_bInitialized) return;
62 
63 			if(NativeLib.IsUnix())
64 			{
65 				try { UnixLoadFonts(); }
66 				catch(Exception) { Debug.Assert(false); }
67 			}
68 
69 			if(m_fontUI == null) m_fontUI = SystemFonts.DefaultFont;
70 
71 			if(m_fontList == null)
72 			{
73 				if(UIUtil.VistaStyleListsSupported)
74 				{
75 					string str1 = SystemFonts.IconTitleFont.ToString();
76 					string str2 = SystemFonts.StatusFont.ToString();
77 					if(str1 == str2) m_fontList = SystemFonts.StatusFont;
78 					else m_fontList = m_fontUI;
79 				}
80 				else m_fontList = m_fontUI;
81 			}
82 
83 			m_bInitialized = true;
84 		}
85 
UnixLoadFonts()86 		private static void UnixLoadFonts()
87 		{
88 			// string strSession = Environment.GetEnvironmentVariable("DESKTOP_SESSION");
89 			// "Default", "KDE", "Gnome", "Ubuntu", ...
90 			// string strKde = Environment.GetEnvironmentVariable("KDE_FULL_SESSION");
91 
92 			string strHome = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
93 			if(string.IsNullOrEmpty(strHome)) { Debug.Assert(false); return; }
94 			strHome = UrlUtil.EnsureTerminatingSeparator(strHome, false);
95 
96 			KdeLoadFonts(strHome);
97 			if(m_fontUI == null) GnomeLoadFonts(strHome);
98 			if(m_fontUI == null) UbuntuLoadFonts();
99 		}
100 
KdeLoadFonts(string strHome)101 		private static void KdeLoadFonts(string strHome)
102 		{
103 			string strKdeConfig = strHome + ".kde/share/config/kdeglobals";
104 			if(!File.Exists(strKdeConfig))
105 			{
106 				strKdeConfig = strHome + ".kde4/share/config/kdeglobals";
107 				if(!File.Exists(strKdeConfig))
108 				{
109 					strKdeConfig = strHome + ".kde3/share/config/kdeglobals";
110 					if(!File.Exists(strKdeConfig)) return;
111 				}
112 			}
113 
114 			IniFile ini = IniFile.Read(strKdeConfig, Encoding.UTF8);
115 
116 			string strFont = ini.Get("General", "font");
117 			if(string.IsNullOrEmpty(strFont)) { Debug.Assert(false); return; }
118 
119 			m_fontUI = KdeCreateFont(strFont);
120 		}
121 
KdeCreateFont(string strDef)122 		private static Font KdeCreateFont(string strDef)
123 		{
124 			string[] v = strDef.Split(new char[] { ',' });
125 			if((v == null) || (v.Length < 6)) { Debug.Assert(false); return null; }
126 
127 			for(int i = 0; i < v.Length; ++i)
128 				v[i] = v[i].Trim();
129 
130 			float fSize;
131 			if(!float.TryParse(v[1], out fSize)) { Debug.Assert(false); return null; }
132 
133 			FontStyle fs = FontStyle.Regular;
134 			if(v[4] == "75") fs |= FontStyle.Bold;
135 			if((v[5] == "1") || (v[5] == "2")) fs |= FontStyle.Italic;
136 
137 			return FontUtil.CreateFont(v[0], fSize, fs);
138 		}
139 
GnomeLoadFonts(string strHome)140 		private static void GnomeLoadFonts(string strHome)
141 		{
142 			string strConfig = strHome + @".gconf/desktop/gnome/interface/%gconf.xml";
143 			if(!File.Exists(strConfig)) return;
144 
145 			XmlDocument doc = XmlUtilEx.CreateXmlDocument();
146 			doc.Load(strConfig);
147 
148 			foreach(XmlNode xn in doc.DocumentElement.ChildNodes)
149 			{
150 				if(string.Equals(xn.Name, "entry") &&
151 					string.Equals(xn.Attributes.GetNamedItem("name").Value, "font_name"))
152 				{
153 					m_fontUI = GnomeCreateFont(xn.FirstChild.InnerText);
154 					break;
155 				}
156 			}
157 		}
158 
GnomeCreateFont(string strDef)159 		private static Font GnomeCreateFont(string strDef)
160 		{
161 			int iSep = strDef.LastIndexOf(' ');
162 			if(iSep < 0) { Debug.Assert(false); return null; }
163 
164 			string strName = strDef.Substring(0, iSep);
165 
166 			float fSize = float.Parse(strDef.Substring(iSep + 1));
167 
168 			FontStyle fs = FontStyle.Regular;
169 			// Name can end with "Bold", "Italic", "Bold Italic", ...
170 			if(strName.EndsWith(" Oblique", StrUtil.CaseIgnoreCmp)) // Gnome
171 			{
172 				fs |= FontStyle.Italic;
173 				strName = strName.Substring(0, strName.Length - 8);
174 			}
175 			if(strName.EndsWith(" Italic", StrUtil.CaseIgnoreCmp)) // Ubuntu
176 			{
177 				fs |= FontStyle.Italic;
178 				strName = strName.Substring(0, strName.Length - 7);
179 			}
180 			if(strName.EndsWith(" Bold", StrUtil.CaseIgnoreCmp))
181 			{
182 				fs |= FontStyle.Bold;
183 				strName = strName.Substring(0, strName.Length - 5);
184 			}
185 
186 			return FontUtil.CreateFont(strName, fSize, fs);
187 		}
188 
UbuntuLoadFonts()189 		private static void UbuntuLoadFonts()
190 		{
191 			string strDef = NativeLib.RunConsoleApp("gsettings",
192 				"get org.gnome.desktop.interface font-name");
193 			if(strDef == null) return;
194 
195 			strDef = strDef.Trim(new char[] { ' ', '\t', '\r', '\n', '\'', '\"' });
196 			if(strDef.Length == 0) return;
197 
198 			m_fontUI = GnomeCreateFont(strDef);
199 		}
200 	}
201 }
202