Download DLL - 4.59 KB
Introduction
Due to the lack of Right to Left (RTL) language support like Persian/Farsi in Silverlight 2.0, RTL texts are not rendered correctly in Silverlight. This project is a helper library to allow using Persian texts in Silverlight 2.0.
The source code is hosted on the CodePlex as an open source project available here.
Code Description
PersianCharacter.cs
class is used to define a Persian Character Map.
internal class PersianCharacter
{
public PersianCharacter(string characterName, bool noLastAppend, int
startChar, int middleRightSideBoundedChar, int
middleLeftSideBoundedChar, int middleTwoSideBoundedChar, int
endingBoundedChar, int endingChar)
{
CharacterName = characterName;
NoLastAppend = noLastAppend;
StartChar = startChar;
MiddleRightSideBoundedChar = middleRightSideBoundedChar;
MiddleLeftSideBoundedChar = middleLeftSideBoundedChar;
MiddleTwoSideBoundedChar = middleTwoSideBoundedChar;
EndingBoundedChar = endingBoundedChar;
EndingChar = endingChar;
}
private string _CharacterName = "";
public string CharacterName
{
get
{
return _CharacterName;
}
set
{
_CharacterName = value;
}
}
private bool _NoLastAppend = false;
public bool NoLastAppend
{
get
{
return _NoLastAppend;
}
set
{
_NoLastAppend = value;
}
}
private int _StartChar = 0;
public int StartChar
{
get
{
return _StartChar;
}
set
{
_StartChar = value;
}
}
private int _MiddleRightSideBoundedChar = 0;
public int MiddleRightSideBoundedChar
{
get
{
return _MiddleRightSideBoundedChar;
}
set
{
_MiddleRightSideBoundedChar = value;
}
}
private int _MiddleLeftSideBoundedChar = 0;
public int MiddleLeftSideBoundedChar
{
get
{
return _MiddleLeftSideBoundedChar;
}
set
{
_MiddleLeftSideBoundedChar = value;
}
}
private int _MiddleTwoSideBoundedChar = 0;
public int MiddleTwoSideBoundedChar
{
get
{
return _MiddleTwoSideBoundedChar;
}
set
{
_MiddleTwoSideBoundedChar = value;
}
}
private int _EndingBoundedChar = 0;
public int EndingBoundedChar
{
get
{
return _EndingBoundedChar;
}
set
{
_EndingBoundedChar = value;
}
}
private int _EndingChar = 0;
public int EndingChar
{
get
{
return _EndingChar;
}
set
{
_EndingChar = value;
}
}
}
PersianMaker.cs
class does the process of formatting a Persian string. It has five methods which I will discuss briefly here.
First, we define all the Persian characters and add them to the CharacterMap
list. There are about 40 characters, even though the actual Persian characters count is less than 40. There are some Arabic characters which are used nowadays in Persian writing. After populating the Character Map with the objects of PersianCharacter
class, it will be ready to be used. Thanks to LINQ for supporting LINQ to Objects because it reduces the number of loops.
IsPersianCharacter
method is for checking whether a specified character belongs to the Persian Character Map or not. This will be done by querying the CharacterMap
list.
IsNoLastAppendCharacter
which checks if the specified character is a Persian character to which no character can be appended to the end, such as Je(ژ) or Re (ر).
ReverseString
will accept a string, and then return it reversed. We need this method because we should reverse the string to be presented correctly in Silverlight because of the lack of right to left support.
ToPersianString
is the heart of this class because it accepts a raw (unformatted) text and produces a string that can be presented correctly in Silverlight content. This method iterates the text, character by character, to concatenate Persian characters correctly.
ToPersian
first separates words by space, and then passed them to ToPersianString
. Then it concatenates the words and returns the final string that can be presented in Silverlight 2.0 content correctly.
public class PersianMaker
{
private List<PersianCharacter> CharacterMap;
public PersianMaker()
{
CharacterMap = new List<PersianCharacter>();
#region ABaKolah آ
CharacterMap.Add(new PersianCharacter("ABaKolah", true,
0x622, 0x622, 0xfe82, 0xfe81, 0xfe82, 0xfe81));
# endregion
#region Alef ا
CharacterMap.Add(new PersianCharacter("Alef", true, 0x627,
0x627, 0xfe8e, 0xfe8d, 0xfe8e, 0xfe8d));
# endregion
#region AlefWithHamzeAbove أ
CharacterMap.Add(new PersianCharacter("AlefWithHamzeAbove",
true, 0x623, 0x623, 0xfe84, 0xfe83, 0xfe84, 0xfe83));
# endregion
#region AlefWithHamzeBelow إ
CharacterMap.Add(new PersianCharacter("AlefWithHamzeBelow",
true, 0x625, 0x625, 0xfe88, 0xfe87, 0xfe88, 0xfe87));
# endregion
#region Hamze ء
CharacterMap.Add(new PersianCharacter("Hamze", true,
0x621, 0x621, 0xfe80, 0xfe80, 0xfe80, 0xfe7f));
# endregion
#region Be ب
CharacterMap.Add(new PersianCharacter("Be", false,
0x628, 0x628, 0xfe90, 0xfe91, 0xfe92, 0xfe8f));
# endregion
#region Pe پ
CharacterMap.Add(new PersianCharacter("Pe", false,
0x67e, 0x67e, 0xfb57, 0xfb58, 0xfb59, 0xfb56));
# endregion
#region Te ت
CharacterMap.Add(new PersianCharacter("Te", false,
0x62a, 0x62a, 0xfe96, 0xfe97, 0xfe98, 0xfe95));
# endregion
#region Theh ث
CharacterMap.Add(new PersianCharacter("Theh", false,
0x62b, 0x62b, 0xfe9a, 0xfe9b, 0xfe9c, 0xfe99));
# endregion
#region Jeem ج
CharacterMap.Add(new PersianCharacter("Jeem", false,
0x62c, 0x62c, 0xfe9e, 0xfe9f, 0xfea0, 0xfe9d));
# endregion
#region Che چ
CharacterMap.Add(new PersianCharacter("Che", false,
0x686, 0x686, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7a));
# endregion
#region Hah ح
CharacterMap.Add(new PersianCharacter("Hah", false,
0x62d, 0x62d, 0xfea2, 0xfea3, 0xfea4, 0xfea1));
# endregion
#region Kheh خ
CharacterMap.Add(new PersianCharacter("Kheh", false,
0x62e, 0x62e, 0xfea6, 0xfea7, 0xfea8, 0xfea5));
# endregion
#region Dal د
CharacterMap.Add(new PersianCharacter("Dal", true,
0x62f, 0x62f, 0xfeaa, 0xfea9, 0xfeaa, 0xfea9));
# endregion
#region Zal ذ
CharacterMap.Add(new PersianCharacter("Zal", true,
0x630, 0x630, 0xfeac, 0xfeab, 0xfeac, 0xfeab));
# endregion
#region Re ر
CharacterMap.Add(new PersianCharacter("Re", true, 0x631,
0x631, 0xfeae, 0xfead, 0xfeae, 0xfead));
# endregion
#region Ze ز
CharacterMap.Add(new PersianCharacter("Ze", true,
0x632, 0x632, 0xfeb0, 0xfeaf, 0xfeb0, 0xfeaf));
# endregion
#region Je ژ
CharacterMap.Add(new PersianCharacter("Je", true,
0x698, 0x698, 0xfb8b, 0xfb8a, 0xfb8b, 0xfb8a));
# endregion
#region Seen س
CharacterMap.Add(new PersianCharacter("Seen", false,
0x633, 0x633, 0xfeb2, 0xfeb3, 0xfeb4, 0xfeb1));
# endregion
#region Sheen ش
CharacterMap.Add(new PersianCharacter("Sheen", false,
0x634, 0x634, 0xfeb6, 0xfeb7, 0xfeb8, 0xfeb5));
# endregion
#region Sad ص
CharacterMap.Add(new PersianCharacter("Sad", false,
0x635, 0x635, 0xfeba, 0xfebb, 0xfebc, 0xfeb9));
# endregion
#region Zad ض
CharacterMap.Add(new PersianCharacter("Zad", false,
0x636, 0x636, 0xfebe, 0xfebf, 0xfec0, 0xfebd));
# endregion
#region Ta ط
CharacterMap.Add(new PersianCharacter("Ta", false,
0x637, 0x637, 0xfec2, 0xfec3, 0xfec4, 0xfec1));
# endregion
#region Za ظ
CharacterMap.Add(new PersianCharacter("Za", false,
0x638, 0x638, 0xfec6, 0xfec7, 0xfec8, 0xfec5));
# endregion
#region Ein ع
CharacterMap.Add(new PersianCharacter("Ein", false,
0x639, 0xfeca, 0xfeca, 0xfecb, 0xfecc, 0xfec9));
# endregion
#region Ghein غ
CharacterMap.Add(new PersianCharacter("Ghein", false,
0x63a, 0x63a, 0xfece, 0xfecf, 0xfed0, 0xfecd));
# endregion
#region Fe ف
CharacterMap.Add(new PersianCharacter("Fe", false,
0x641, 0x641, 0xfed2, 0xfed3, 0xfed4, 0xfed1));
# endregion
#region Ghaf ق
CharacterMap.Add(new PersianCharacter("Ghaf", false,
0x642, 0x642, 0xfed6, 0xfed7, 0xfed8, 0xfed5));
# endregion
#region kaf ک
CharacterMap.Add(new PersianCharacter("kaf", false,
0x6a9, 0x6a9, 0xfeda, 0xfedb, 0xfedc, 0xfed9));
# endregion
#region Gaf گ
CharacterMap.Add(new PersianCharacter("Gaf", false,
0x6af, 0x6af, 0xfb93, 0xfb94, 0xfb95, 0xfb92));
# endregion
#region Lam ل
CharacterMap.Add(new PersianCharacter("Lam", false,
0x644, 0x644, 0xfede, 0xfedf, 0xfee0, 0xfedd));
# endregion
#region Meem م
CharacterMap.Add(new PersianCharacter("Meem", false,
0x645, 0x645, 0xfee2, 0xfee3, 0xfee4, 0xfee1));
# endregion
#region Noon ن
CharacterMap.Add(new PersianCharacter("Noon", false,
0x646, 0x646, 0xfee6, 0xfee7, 0xfee8, 0xfee5));
# endregion
#region Vav و
CharacterMap.Add(new PersianCharacter("Vav", true, 0x648,
0x648, 0xfeee, 0xfeed, 0xfeee, 0xfeed));
# endregion
#region VavBaHamze ؤ
CharacterMap.Add(new PersianCharacter("VavBaHamze", true,
0x624, 0x624, 0xfe86, 0xfe85, 0xfe86, 0xfe85));
# endregion
#region Heh ه
CharacterMap.Add(new PersianCharacter("Heh", false,
0x647, 0x647, 0xfeea, 0xfeeb, 0xfeec, 0xfee9));
# endregion
#region TehMarbuta ة
CharacterMap.Add(new PersianCharacter("TehMarbuta",
true, 0x629, 0x629, 0xfe94, 0xfe93, 0xfe93, 0xfe93));
# endregion
#region Ye ی
CharacterMap.Add(new PersianCharacter("Ye", false,
0x6cc, 0x6cc, 0xfef0, 0xfef3, 0xfef4, 0xfeef));
# endregion
#region ArabicYe ي
CharacterMap.Add(new PersianCharacter("ArabicYe", false,
0x64a, 0x64a, 0xfef2, 0xfef3, 0xfef4, 0xfef1));
# endregion
#region YeBaHamze ئ
CharacterMap.Add(new PersianCharacter("YeBaHamze", false,
0x626, 0x626, 0xfe8a, 0xfe8b, 0xfe8c, 0xfe89));
# endregion
}
private bool IsPersianCharacter(char ch)
{
bool result = false;
var query = from cm in CharacterMap
where cm.StartChar == ch ||
cm.MiddleRightSideBoundedChar == ch ||
cm.MiddleLeftSideBoundedChar == ch ||
cm.MiddleTwoSideBoundedChar == ch ||
cm.EndingBoundedChar == ch ||
cm.EndingChar == ch
select cm.CharacterName;
if (query.Count() > 0)
{
result = true;
}
return result;
}
private bool IsNoLastAppendCharacter(char ch)
{
bool result = false;
var query = from cm in CharacterMap
where (cm.StartChar == ch ||
cm.MiddleRightSideBoundedChar == ch ||
cm.MiddleLeftSideBoundedChar == ch ||
cm.MiddleTwoSideBoundedChar == ch ||
cm.EndingBoundedChar == ch ||
cm.EndingChar == ch) & cm.NoLastAppend == true
select cm.NoLastAppend;
if (query.Count() > 0)
{
result = true;
}
return result;
}
private string ToPersianString(string text)
{
int i = 0;
string str2 = "";
while (i < text.Length)
{
ECharPossition possition= ECharPossition.StartingChar;
if (IsPersianCharacter(Convert.ToChar(text.Substring(i, 1))))
{
if (i == 0)
{
possition = ECharPossition.StartingChar;
}
else if (i == (text.Length - 1))
{
if (IsPersianCharacter(Convert.ToChar(text.Substring(i - 1, 1))))
{
if (IsNoLastAppendCharacter(
Convert.ToChar(text.Substring(i - 1, 1))))
{
possition = ECharPossition.EndingChar;
}
else
{
possition = ECharPossition.EndingBoundedChar;
}
}
else
{
possition = ECharPossition.EndingBoundedChar;
}
}
else
{
if (IsPersianCharacter(
Convert.ToChar(text.Substring(i - 1, 1))))
{
if (IsNoLastAppendCharacter(
Convert.ToChar(text.Substring(i - 1, 1))))
{
if (IsPersianCharacter(
Convert.ToChar(text.Substring(i, 1))))
{
if (!IsNoLastAppendCharacter(
Convert.ToChar(text.Substring(i, 1))))
{
possition =
ECharPossition.MiddleLeftSideBoundedChar;
}
else
{
possition = ECharPossition.StartingChar;
}
}
else
{
possition = ECharPossition.StartingChar;
}
}
else
{
possition = ECharPossition.MiddleTwoSidesBoundedChar;
}
}
else
{
possition = ECharPossition.StartingChar;
}
}
char currentChar = Convert.ToChar(text.Substring(i, 1));
var query = from cm in CharacterMap
where cm.StartChar == currentChar ||
cm.MiddleRightSideBoundedChar == currentChar ||
cm.MiddleLeftSideBoundedChar == currentChar ||
cm.MiddleTwoSideBoundedChar == currentChar ||
cm.EndingBoundedChar == currentChar ||
cm.EndingChar == currentChar
select cm;
PersianCharacter pch = query.First();
if (pch != null)
{
switch (possition)
{
case ECharPossition.StartingChar:
str2 = str2 +
Convert.ToChar(pch.MiddleTwoSideBoundedChar).ToString();
break;
case ECharPossition.MiddleRightSideBoundedChar: ;
str2 = str2 +
Convert.ToChar(pch.EndingBoundedChar).ToString();
break;
case ECharPossition.MiddleLeftSideBoundedChar:
str2 = str2 +
Convert.ToChar(pch.MiddleTwoSideBoundedChar).ToString();
break;
case ECharPossition.MiddleTwoSidesBoundedChar:
str2 = str2 +
Convert.ToChar(pch.EndingBoundedChar).ToString();
break;
case ECharPossition.EndingBoundedChar:
str2 = str2 +
Convert.ToChar(pch.MiddleLeftSideBoundedChar).ToString();
break;
case ECharPossition.EndingChar:
str2 = str2 + Convert.ToChar(pch.EndingChar).ToString();
break;
default:
break;
}
}
}
else
{
str2 = str2 + text.Substring(i, 1);
}
i++;
}
return this.ReverseString(str2);
}
public string ToPersian(string text)
{
string str = "";
string[] strArray0 = text.Split('\n');
for (int j = strArray0.Length - 1; j >= 0; j--)
{
string[] strArray1 = strArray0[j].Split(new char[] { ' ' });
int upperBound = strArray1.GetUpperBound(0);
for (int i = 0; i <= upperBound; i++)
{
str = this.ToPersianString(strArray1[i]) + " " + str;
}
str = "\n" + str;
}
str.Trim();
return str;
}
private string ReverseString(string str)
{
string str2 = "";
for (int i = str.Length - 1; i >= 0; i--)
{
if (IsPersianCharacter(Convert.ToChar(str.Substring(i, 1))))
{
str2 = str2 + str.Substring(i, 1);
}
else
{
str2 = str.Substring(i, 1) + str2;
}
}
return str2;
}
private enum ECharPossition
{
StartingChar,
MiddleRightSideBoundedChar,
MiddleLeftSideBoundedChar,
MiddleTwoSidesBoundedChar,
EndingBoundedChar,
EndingChar
}
}
Using the code
The source code of this project is available here.