Skip to content

Commit 34e58fe

Browse files
committed
publish project
1 parent 95deea8 commit 34e58fe

File tree

97 files changed

+18916
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+18916
-1
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2022 DebugST
3+
Copyright (c) 2022 STTextBox
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

ST.Library.Drawing/EmojiRender.cs

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
using ST.Library.UI.STTextBox;
7+
using ST.Library.Drawing.SvgRender;
8+
9+
using System.IO;
10+
using System.Drawing;
11+
using System.Drawing.Imaging;
12+
using System.Runtime.InteropServices;
13+
using System.Text.RegularExpressions;
14+
15+
namespace ST.Library.Drawing
16+
{
17+
public class EmojiRender : IEmojiRender, IDisposable
18+
{
19+
private Dictionary<string, string> m_dic_xml = new Dictionary<string, string>();
20+
private Dictionary<string, CacheInfo> m_dic_cache = new Dictionary<string, CacheInfo>();
21+
22+
private struct CacheInfo
23+
{
24+
public int Size;
25+
public Image Image;
26+
public Image SelectedImage;
27+
}
28+
29+
private ImageAttributes m_img_attr_normal;
30+
private ImageAttributes m_img_attr_selected;
31+
32+
public EmojiRender(string strFile) {
33+
ColorMatrix m = new ColorMatrix(new float[][]{
34+
new float[]{1, 0, 0, 0, 0},
35+
new float[]{0, 1, 0, 0, 0},
36+
new float[]{0, 0, 1, 0, 0},
37+
new float[]{0, 0, 0, 1, 0},
38+
new float[]{0, 0, 0, 0, 1},
39+
});
40+
m_img_attr_normal = new ImageAttributes();
41+
m_img_attr_normal.SetColorMatrix(m);
42+
m[3, 3] = 0.5F;
43+
m_img_attr_selected = new ImageAttributes();
44+
m_img_attr_selected.SetColorMatrix(m);
45+
this.InitSvgFromPackage(strFile);
46+
}
47+
48+
public bool IsEmoji(string strChar) {
49+
return this.GetEmojiString(strChar) != null;
50+
}
51+
52+
private string GetEmojiString(string strText) {
53+
if (m_dic_xml.ContainsKey(strText)) {
54+
return strText;
55+
}
56+
// http://www.unicode.org/charts/PDF/UFE00.pdf
57+
// FE00 - FE0F is the Variation Selectors
58+
// FE0E -> text variation selector
59+
// FE0F -> emoji variation selector
60+
if (strText.IndexOf('\uFE0F') == -1) {
61+
return null;
62+
}
63+
strText = strText.Replace("\uFE0F", "");// strText.Substring(0, strText.Length - 1);
64+
if (m_dic_xml.ContainsKey(strText)) {
65+
return strText;
66+
}
67+
return null;
68+
}
69+
70+
public void DrawEmoji(ISTTextBoxRender render, string strChar, int nX, int nY, int nWidth, bool bSelected) {
71+
strChar = this.GetEmojiString(strChar);
72+
CacheInfo ci;
73+
if (string.IsNullOrEmpty(strChar)) {
74+
strChar = "none";
75+
}
76+
if (m_dic_cache.ContainsKey(strChar)) {
77+
ci = m_dic_cache[strChar];
78+
if (ci.Size != nWidth) {
79+
ci.Image.Dispose();
80+
ci.Image = this.GetEmojiImage(strChar, nWidth);
81+
m_dic_cache[strChar] = ci;
82+
}
83+
} else {
84+
ci.Size = nWidth;
85+
ci.Image = this.GetEmojiImage(strChar, nWidth);
86+
ci.SelectedImage = this.SetAlpha((Bitmap)ci.Image.Clone());
87+
m_dic_cache.Add(strChar, ci);
88+
}
89+
Rectangle rect = new Rectangle(nX, nY, nWidth, nWidth);
90+
render.DrawImage(bSelected ? ci.SelectedImage : ci.Image, rect);
91+
//if (!bSelected) {
92+
// render.DrawImage(ci.Image, rect);
93+
//} else {
94+
// using (Bitmap bmp = (Bitmap)ci.Image.Clone()) {
95+
// var bmpData = bmp.LockBits(new Rectangle(0, 0, nWidth, nWidth), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
96+
// byte[] byClr = new byte[bmpData.Stride * bmpData.Height];
97+
// Marshal.Copy(bmpData.Scan0, byClr, 0, byClr.Length);
98+
// for (int x = 0; x < bmp.Width; x++) {
99+
// for (int y = 0; y < bmp.Height; y++) {
100+
// int nIndex = y * bmpData.Stride + x * 4 + 3;
101+
// byClr[nIndex] = (byte)(byClr[nIndex] >> 1);
102+
// }
103+
// }
104+
// Marshal.Copy(byClr, 0, bmpData.Scan0, byClr.Length);
105+
// bmp.UnlockBits(bmpData);
106+
// render.DrawImage(bmp, rect);
107+
// }
108+
//}
109+
}
110+
111+
public Image GetEmojiImage(string strChar, int nSize) {
112+
strChar = this.GetEmojiString(strChar);
113+
if (strChar == null) {
114+
return null;
115+
}
116+
Bitmap bmp = new Bitmap(nSize, nSize);
117+
using (Graphics g = Graphics.FromImage(bmp)) {
118+
using (SvgDocument svg = SvgDocument.FromXml(m_dic_xml[strChar])) {
119+
svg.Draw(g, new RectangleF(0, 0, nSize, nSize));
120+
}
121+
}
122+
return bmp;
123+
}
124+
125+
public Image SetAlpha(Bitmap bmp) {
126+
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
127+
byte[] byClr = new byte[bmpData.Stride * bmpData.Height];
128+
Marshal.Copy(bmpData.Scan0, byClr, 0, byClr.Length);
129+
for (int x = 0; x < bmp.Width; x++) {
130+
for (int y = 0; y < bmp.Height; y++) {
131+
int nIndex = y * bmpData.Stride + x * 4 + 3;
132+
byClr[nIndex] = (byte)(byClr[nIndex] >> 1);
133+
}
134+
}
135+
Marshal.Copy(byClr, 0, bmpData.Scan0, byClr.Length);
136+
bmp.UnlockBits(bmpData);
137+
return bmp;
138+
}
139+
140+
private int InitSvgFromPackage(string strFile) {
141+
int nCounter = 0;
142+
Dictionary<string, string> dic = new Dictionary<string, string>();
143+
using (StreamReader reader = new StreamReader(strFile, Encoding.UTF8)) {
144+
string strLine = string.Empty;
145+
while ((strLine = reader.ReadLine()) != null) {
146+
int nIndex = strLine.IndexOf(',');
147+
string strXml = strLine.Substring(nIndex + 1);
148+
dic.Add(this.GetString(strLine.Substring(0, nIndex)), strXml);
149+
}
150+
}
151+
if (!dic.ContainsKey("none")) {
152+
dic.Add("none", "<svg viewBox='0,0,20,20'><rect stroke='red' fill='yellow' x='4' y='2' width='12' height='16'/><path stroke='red' fill='none' d='M8,8 v-2 h4 v4 h-2 v2'/><line stroke='red' x1='8' y1='14' x2='12' y2='14'/></svg>");
153+
}
154+
m_dic_xml = dic;
155+
return nCounter;
156+
}
157+
158+
public string GetString(string strText) {
159+
StringBuilder sb = new StringBuilder();
160+
for (int i = 0; i < strText.Length; i += 4) {
161+
sb.Append((char)(Convert.ToInt32(strText.Substring(i, 4), 16)));
162+
}
163+
return sb.ToString();
164+
}
165+
/// <summary>
166+
/// Package all svg files to one file
167+
/// </summary>
168+
/// <param name="strSvgFilesPath">The svg path</param>
169+
/// <param name="strFileOut">The out file</param>
170+
/// <returns>Svg count</returns>
171+
public static int PackageSvgFiles(string strSvgFilesPath, string strFileOut) {
172+
int nCounter = 0;
173+
Regex reg_start = new Regex(@"^\s+|\s+$", RegexOptions.Multiline);
174+
using (StreamWriter writer = new StreamWriter(strFileOut, false, Encoding.UTF8)) {
175+
foreach (var v in Directory.GetFiles(strSvgFilesPath, "*.svg")) {
176+
string strName = Path.GetFileNameWithoutExtension(v);
177+
string strText = EmojiRender.FileNameToUnicode(strName);
178+
string strXml = File.ReadAllText(v).Trim();
179+
strXml = reg_start.Replace(strXml, "").Replace("\r", "").Replace("\n", "");
180+
writer.WriteLine(strText + "," + strXml);
181+
nCounter++;
182+
}
183+
}
184+
return nCounter;
185+
}
186+
187+
private static string FileNameToUnicode(string strName) {
188+
//((strText[nIndex] & 0x03FF) << 10) + (strText[nIndex + 1] & 0x03FF) + 0x10000;
189+
strName.ToLower();
190+
if (strName[0] == 'u') {
191+
strName = strName.Substring(1);
192+
}
193+
string strRet = string.Empty;
194+
foreach (var v in strName.Split('-', '_')) {
195+
int number = Convert.ToInt32(v, 16);
196+
if (number < 0x10000) {
197+
strRet += number.ToString("X4");
198+
} else {
199+
number &= 0xFFFF;
200+
int nH = (number >> 10) | 0xD800; //D800-DBFF -> hight
201+
int nL = (number & 0x03FF) | 0xDC00; //DC00-DEFF -> low
202+
strRet += nH.ToString("X4");
203+
strRet += nL.ToString("X4");
204+
}
205+
}
206+
return strRet;
207+
}
208+
209+
public void Dispose() {
210+
if (m_img_attr_normal != null) {
211+
m_img_attr_normal.Dispose();
212+
}
213+
if (m_img_attr_selected != null) {
214+
m_img_attr_selected.Dispose();
215+
}
216+
}
217+
}
218+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("ST.Library.Drawing")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("Microsoft")]
12+
[assembly: AssemblyProduct("ST.Library.Drawing")]
13+
[assembly: AssemblyCopyright("Copyright © Microsoft 2022")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("e5f7d8f0-33f0-4f01-a860-0e96e3810dfa")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6+
<ProductVersion>8.0.30703</ProductVersion>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{9D106212-8DD0-46D1-AC7B-FC8C78B71686}</ProjectGuid>
9+
<OutputType>Library</OutputType>
10+
<AppDesignerFolder>Properties</AppDesignerFolder>
11+
<RootNamespace>ST.Library.Drawing</RootNamespace>
12+
<AssemblyName>ST.Library.Drawing</AssemblyName>
13+
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
14+
<FileAlignment>512</FileAlignment>
15+
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
16+
</PropertyGroup>
17+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<DebugType>pdbonly</DebugType>
28+
<Optimize>true</Optimize>
29+
<OutputPath>bin\Release\</OutputPath>
30+
<DefineConstants>TRACE</DefineConstants>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
</PropertyGroup>
34+
<ItemGroup>
35+
<Reference Include="System" />
36+
<Reference Include="System.Core" />
37+
<Reference Include="System.Drawing" />
38+
<Reference Include="System.Xml.Linq" />
39+
<Reference Include="System.Data.DataSetExtensions" />
40+
<Reference Include="System.Data" />
41+
<Reference Include="System.Xml" />
42+
</ItemGroup>
43+
<ItemGroup>
44+
<Compile Include="EmojiRender.cs" />
45+
<Compile Include="Properties\AssemblyInfo.cs" />
46+
<Compile Include="SvgRender\SvgAttributes.cs" />
47+
<Compile Include="SvgRender\SvgAttributes.static.cs" />
48+
<Compile Include="SvgRender\SvgDocument.cs" />
49+
<Compile Include="SvgRender\SvgDocument.static.cs" />
50+
<Compile Include="SvgRender\SvgElement.cs" />
51+
<Compile Include="SvgRender\SvgElementAttribute.cs" />
52+
<Compile Include="SvgRender\SvgElementCollection.cs" />
53+
<Compile Include="SvgRender\SvgElements\SvgCircle.cs" />
54+
<Compile Include="SvgRender\SvgElements\SvgDefs.cs" />
55+
<Compile Include="SvgRender\SvgElements\SvgEllipse.cs" />
56+
<Compile Include="SvgRender\SvgElements\SvgG.cs" />
57+
<Compile Include="SvgRender\SvgElements\SvgGradientBrush.cs" />
58+
<Compile Include="SvgRender\SvgElements\SvgLine.cs" />
59+
<Compile Include="SvgRender\SvgElements\SvgLinearGradient.cs" />
60+
<Compile Include="SvgRender\SvgElements\SvgPath.A2C.cs" />
61+
<Compile Include="SvgRender\SvgElements\SvgPath.cs" />
62+
<Compile Include="SvgRender\SvgElements\SvgPolygon.cs" />
63+
<Compile Include="SvgRender\SvgElements\SvgPolyline.cs" />
64+
<Compile Include="SvgRender\SvgElements\SvgRadialGradient.cs" />
65+
<Compile Include="SvgRender\SvgElements\SvgRect.cs" />
66+
<Compile Include="SvgRender\SvgElements\SvgStop.cs" />
67+
<Compile Include="SvgRender\SvgElements\SvgUse.cs" />
68+
</ItemGroup>
69+
<ItemGroup>
70+
<ProjectReference Include="..\ST.Library.UI.STTextBox\ST.Library.UI.STTextBox.csproj">
71+
<Project>{429ED407-C992-467B-AFE2-EDA3206ACFFB}</Project>
72+
<Name>ST.Library.UI.STTextBox</Name>
73+
</ProjectReference>
74+
</ItemGroup>
75+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
76+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
77+
Other similar extension points exist, see Microsoft.Common.targets.
78+
<Target Name="BeforeBuild">
79+
</Target>
80+
<Target Name="AfterBuild">
81+
</Target>
82+
-->
83+
</Project>

0 commit comments

Comments
 (0)