├── .gitignore
├── _info
└── patch1.jpg
├── TelegramFontPatcher
├── App.config
├── StringExtensions.cs
├── PatternList.cs
├── Properties
│ └── AssemblyInfo.cs
├── TelegramFontPatcher.csproj
├── BinaryUtility.cs
└── Program.cs
├── TelegramFontPatcher.sln.DotSettings.user
├── fix_telegram_fonts.reg
├── README.md
└── TelegramFontPatcher.sln
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | /packages/
4 | .idea/
5 | .vs/
6 |
--------------------------------------------------------------------------------
/_info/patch1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grandsilence/telegram-font-patcher-csharp/HEAD/_info/patch1.jpg
--------------------------------------------------------------------------------
/TelegramFontPatcher/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TelegramFontPatcher/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace TelegramFontPatcher
4 | {
5 | internal static class StringExtensions
6 | {
7 | public static byte[] RawBytes(this string self, Encoding encoding, int length)
8 | {
9 | var result = new byte[encoding.GetMaxByteCount(length)];
10 | encoding.GetBytes(self, 0, self.Length, result, 0);
11 |
12 | return result;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/TelegramFontPatcher.sln.DotSettings.user:
--------------------------------------------------------------------------------
1 |
2 | 0
3 | 0
--------------------------------------------------------------------------------
/fix_telegram_fonts.reg:
--------------------------------------------------------------------------------
1 | Windows Registry Editor Version 5.00
2 |
3 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes]
4 | "DAOpenSans"="Tahoma"
5 | "DAOpenSansBold"="Tahoma"
6 | "DAOpenSansBoldItalic"="Tahoma"
7 | "DAOpenSansRegular"="Tahoma"
8 | "DAOpenSansRegularItalic"="Tahoma"
9 | "DAOpenSansSemibold"="Tahoma"
10 | "DAOpenSansSemiboldItalic"="Tahoma"
11 | "DAVazir"="Tahoma"
12 | "DAVazirBold"="Tahoma"
13 | "DAVazirMedium"="Tahoma"
14 | "DAVazirRegular"="Tahoma"
15 | ;; Priority font resolving: "Cascadia Mono", "Consolas", "Liberation Mono", "Menlo", "Courier"
16 | ;; Override monospace font:
17 | "Cascadia Mono"="Fixedsys"
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Telegram Desktop (Windows) Font Patcher
2 |
3 | > DEPRECATED!
4 | > Use [fix_telegram_fonts.reg](fix_telegram_fonts.reg) to override fonts without patching EXE.
5 | > In 5.0.0 Telegram Desktop you should set `Chat settings -> Font family option` to `System Value`.
6 |
7 | All [telegram fonts can be found in lib_ui](https://github.com/desktop-app/lib_ui/tree/master/fonts) and [implementaion of font selection is here](https://github.com/desktop-app/lib_ui/blob/master/ui/style/style_core_font.cpp).
8 |
9 | ---
10 |
11 | ## About project
12 |
13 | Patch Telegram fonts to Arial / Tahoma. Makes text more clear.
14 | It's slow but working. If you have a time make it faster on C++.
15 |
--------------------------------------------------------------------------------
/TelegramFontPatcher/PatternList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace TelegramFontPatcher
6 | {
7 | internal class PatternList : List>
8 | {
9 | public PatternList(string newFont, IEnumerable oldFonts)
10 | {
11 | foreach (string oldFont in oldFonts)
12 | {
13 | Add(oldFont, newFont, Encoding.ASCII);
14 | Add(oldFont, newFont, Encoding.Unicode);
15 | }
16 | }
17 |
18 | private void Add(string oldFont, string newFont, Encoding encoding)
19 | {
20 | Add(new Tuple(oldFont.RawBytes(encoding, oldFont.Length), newFont.RawBytes(encoding, oldFont.Length)));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/TelegramFontPatcher.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2015
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramFontPatcher", "TelegramFontPatcher\TelegramFontPatcher.csproj", "{D2DDBFA4-1082-4DFE-8512-3C9220237270}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | Release|x64 = Release|x64
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}.Debug|Any CPU.Build.0 = Debug|Any CPU
17 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}.Release|x64.ActiveCfg = Release|x64
20 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}.Release|x64.Build.0 = Release|x64
21 | EndGlobalSection
22 | GlobalSection(SolutionProperties) = preSolution
23 | HideSolutionNode = FALSE
24 | EndGlobalSection
25 | GlobalSection(ExtensibilityGlobals) = postSolution
26 | SolutionGuid = {92756B5D-F0B2-490B-93B5-45A1B038DBDE}
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/TelegramFontPatcher/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // Общие сведения об этой сборке предоставляются следующим набором
5 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
6 | // связанные со сборкой.
7 | [assembly: AssemblyTitle("Telegram Patcher 2020")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("Telegram Font Patcher 2020")]
12 | [assembly: AssemblyCopyright("Copyright © 2020")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
17 | // для компонентов COM. Если необходимо обратиться к типу в этой сборке через
18 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа.
19 | [assembly: ComVisible(false)]
20 |
21 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
22 | [assembly: Guid("d2ddbfa4-1082-4dfe-8512-3c9220237270")]
23 |
24 | // Сведения о версии сборки состоят из следующих четырех значений:
25 | //
26 | // Основной номер версии
27 | // Дополнительный номер версии
28 | // Номер сборки
29 | // Редакция
30 | //
31 | // Можно задать все значения или принять номер сборки и номер редакции по умолчанию.
32 | // используя "*", как показано ниже:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("2.1.3.0")]
35 | [assembly: AssemblyFileVersion("2.1.3.0")]
36 |
--------------------------------------------------------------------------------
/TelegramFontPatcher/TelegramFontPatcher.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU;x64;x86
7 | {D2DDBFA4-1082-4DFE-8512-3C9220237270}
8 | Exe
9 | TelegramFontPatcher
10 | TelegramFontPatcher
11 | v4.7.2
12 | 512
13 | true
14 | 8
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 | bin\x64\Release\
37 | x64
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/TelegramFontPatcher/BinaryUtility.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 |
6 | //using System.Linq;
7 |
8 | namespace TelegramFontPatcher
9 | {
10 | public static class BinaryUtility
11 | {
12 | public static IEnumerable GetByteStream(BinaryReader reader)
13 | {
14 | const int bufferSize = 1024;
15 | byte[] buffer;
16 | do
17 | {
18 | buffer = reader.ReadBytes(bufferSize);
19 | foreach (var d in buffer) { yield return d; }
20 | } while (bufferSize == buffer.Length);
21 | }
22 |
23 | public static void Replace(BinaryReader reader, BinaryWriter writer, IEnumerable> searchAndReplace)
24 | {
25 | foreach (byte d in Replace(GetByteStream(reader), searchAndReplace))
26 | writer.Write(d);
27 | }
28 |
29 | private static IEnumerable Replace(IEnumerable source, IEnumerable> searchAndReplace)
30 | {
31 | var result = source;
32 | foreach (var tuple in searchAndReplace)
33 | result = Replace(result, tuple.Item1, tuple.Item2);
34 |
35 | return result;
36 | }
37 |
38 | private static IEnumerable Replace(IEnumerable input, IEnumerable from, IEnumerable to)
39 | {
40 | using var fromEnumerator = from.GetEnumerator();
41 | fromEnumerator.MoveNext();
42 | int match = 0;
43 | foreach (var data in input)
44 | {
45 | if (data == fromEnumerator.Current)
46 | {
47 | match++;
48 | if (fromEnumerator.MoveNext()) { continue; }
49 | foreach (byte d in to) { yield return d; }
50 | match = 0;
51 | fromEnumerator.Reset();
52 | fromEnumerator.MoveNext();
53 | continue;
54 | }
55 | if (0 != match)
56 | {
57 | foreach (byte d in from.Take(match)) { yield return d; }
58 | match = 0;
59 | fromEnumerator.Reset();
60 | fromEnumerator.MoveNext();
61 | }
62 | yield return data;
63 | }
64 |
65 | if (0 != match)
66 | {
67 | foreach (byte d in from.Take(match)) { yield return d; }
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/TelegramFontPatcher/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Reflection;
5 |
6 | namespace TelegramFontPatcher
7 | {
8 | internal class Program
9 | {
10 | private const string ProcName = "Telegram";
11 | private const string ExeName = ProcName + ".exe";
12 |
13 | private static void Error(string message)
14 | {
15 | Console.WriteLine($"ERROR: {message}");
16 | Console.ReadLine();
17 | Environment.Exit(1);
18 | }
19 |
20 | private static void Main(string[] args)
21 | {
22 | Console.Title = $"Telegram Font Patcher {Assembly.GetExecutingAssembly().GetName().Version}";
23 | Console.WriteLine(Console.Title + Environment.NewLine);
24 |
25 | var processes = Process.GetProcessesByName("Telegram");
26 | if (processes.Length == 0)
27 | Error(ExeName + " not found");
28 |
29 | // Backup original Telegram.exe
30 | try
31 | {
32 | var proc = processes[0];
33 | string path = proc.MainModule.FileName;
34 |
35 | proc.Kill();
36 | proc.WaitForExit();
37 |
38 | File.Copy(path, path + ".bak", true);
39 | Console.WriteLine("INFO: Backup saved");
40 |
41 | Console.WriteLine($"NOTICE: Trying to patch {ExeName}...");
42 |
43 | var patternsRegular = new PatternList("Arial", new[] {
44 | "Segoe UI",
45 | "Segoe UI Semibold",
46 | "Open Sans",
47 | "Open Sans Semibold",
48 |
49 | "DAOpenSansRegular",
50 | "DAOpenSansRegularItalic",
51 | "DAOpenSansSemiboldAsBold",
52 | "DAOpenSansSemiboldItalicAsBold",
53 | "DAOpenSansSemibold",
54 | "DAOpenSansSemiboldItalic",
55 |
56 | "DAVazirRegular",
57 | "DAVazirMediumAsBold",
58 | "DAVazirMedium",
59 |
60 | "Microsoft YaHei",
61 | "Microsoft JhengHei UI",
62 | "Yu Gothic UI"
63 | });
64 |
65 | string patchedName = path + ".patched";
66 | if (File.Exists(patchedName))
67 | File.Delete(patchedName);
68 |
69 | Console.WriteLine("Patching...");
70 |
71 | using (var reader = new BinaryReader(new FileStream(path, FileMode.Open)))
72 | using (var writer = new BinaryWriter(new FileStream(patchedName, FileMode.Create)))
73 | {
74 | BinaryUtility.Replace(reader, writer, patternsRegular);
75 | }
76 |
77 | File.Delete(path);
78 | File.Move(patchedName, path);
79 |
80 | Process.Start(path);
81 | }
82 | catch (Exception ex)
83 | {
84 | Error(ex.Message);
85 | }
86 | }
87 | }
88 | }
89 |
90 |
--------------------------------------------------------------------------------