-
Notifications
You must be signed in to change notification settings - Fork 10
/
FontDecoder.cs
145 lines (132 loc) · 4.26 KB
/
FontDecoder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace jjget
{
using Mapping = Dictionary<string, Dictionary<string, string>>;
class MappingParseResult
{
public int status;
public Dictionary<string, string> data;
public string error;
}
class FontDecoder
{
private HttpUtil hu;
private Mapping map;
private Action<string, Color> setProgressDelegate;
private bool ignoreDecodingErrors;
public FontDecoder()
{
this.hu = new HttpUtil();
hu.setEncoding("utf-8");
this.loadMappings();
}
public void setIgnoreDecodingErrors(bool ignore)
{
ignoreDecodingErrors = ignore;
}
Regex customChar = new Regex(@"&#x([a-f0-9]{4})");
public string Decode(string ct, string fontName)
{
if (!map.ContainsKey(fontName))
{
setPrompt("下载字体" + fontName + "(已有" + this.map.Count + ")......");
this.loadFont(fontName);
}
var lookup = this.map[fontName];
setPrompt("解码字体" + fontName);
//‌
return customChar.Replace(ct, m =>
{
var r = m.Groups[1].Value.ToLower();
if(!lookup.ContainsKey(r) && !ignoreDecodingErrors)
{
throw new FontDecoderException("字体" + fontName + "中的字符" + r + "无法解码");
}
return lookup[r];
});
}
private void loadFont(string fontName)
{
string ct = null;
for (int i = 1; i<3; i++)
{
try
{
ct = hu.Get("https://jjwxc.yooooo.us/" + fontName + ".json?version=" + Application.ProductVersion);
break;
}catch(Exception ex)
{
setPrompt("字体下载失败" + ex.ToString(), Color.Orange);
}
}
if(ct == null)
{
throw new FontDecoderException("无法下载字体" + fontName);
}
MappingParseResult r = JsonConvert.DeserializeObject<MappingParseResult>(ct);
if (r.status != 0)
{
throw new FontDecoderException("无法解析字体" + fontName + ": " + ct);
}
this.map[fontName] = r.data;
// only cache if response count is expected
if (r.data.Count == 200)
{
this.saveMappings();
}
}
private void loadMappings()
{
try
{
FileStream fs = new FileStream(".jjfont", FileMode.Open);
using (StreamReader sr = new StreamReader(fs))
{
var s = sr.ReadToEnd();
this.map = JsonConvert.DeserializeObject<Mapping>(s);
}
fs.Close();
}
catch (Exception)
{
this.map = new Mapping();
}
}
public void saveMappings()
{
FileStream fs = new FileStream(".jjfont", FileMode.Create, FileAccess.Write);
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(fs))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, this.map);
}
fs.Close();
}
public void registerSetProgressDelegate(Action<String, Color> d)
{
this.setProgressDelegate = d;
}
private void setPrompt(string text)
{
setProgressDelegate(text, Color.Green);
}
private void setPrompt(string text, Color c)
{
setProgressDelegate("FD:" + text, c);
}
}
public class FontDecoderException : Exception
{
public FontDecoderException() : base() { }
public FontDecoderException(string s) : base(s) { }
}
}