65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 2.0 的波斯语 (Farsi) 语言支持

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (8投票s)

2008 年 10 月 22 日

Ms-PL

2分钟阅读

viewsIcon

35316

downloadIcon

269

Silverlight 2.0 的波斯语 (Farsi) 语言支持

下载 DLL - 4.59 KB

引言

由于 Silverlight 2.0 缺乏对从右到左 (RTL) 语言(例如波斯语/Farsi)的支持,因此 RTL 文本在 Silverlight 中无法正确呈现。此项目是一个辅助库,允许在 Silverlight 2.0 中使用波斯语文本。

源代码托管在 CodePlex 上,作为一个开放源代码项目,可在此处获得

代码描述

PersianCharacter.cs 类用于定义波斯语字符映射。

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 类负责格式化波斯语字符串的过程。它有五个方法,我将在这里简要讨论。

首先,我们定义所有波斯语字符,并将它们添加到 CharacterMap 列表中。大约有 40 个字符,即使实际的波斯语字符数少于 40 个。有些阿拉伯字符现在在波斯语写作中使用。使用 PersianCharacter 类的对象填充字符映射后,就可以使用了。感谢 LINQ 对 LINQ to Objects 的支持,因为它减少了循环次数。

IsPersianCharacter 方法用于检查指定的字符是否属于波斯语字符映射。 这将通过查询 CharacterMap 列表来完成。

IsNoLastAppendCharacter 检查指定的字符是否为不能在末尾追加字符的波斯语字符,例如 Je(ژ) 或 Re (ر)。

ReverseString 将接受一个字符串,然后将其反转。我们需要此方法,因为我们应该反转字符串才能在 Silverlight 中正确显示,因为缺少从右到左的支持。

ToPersianString 是这个类的核心,因为它接受原始(未格式化)的文本,并生成可以在 Silverlight 内容中正确显示的字符串。此方法逐个字符地迭代文本,以正确地连接波斯语字符。

ToPersian 首先按空格分隔单词,然后将它们传递给 ToPersianString。然后它连接单词并返回可以在 Silverlight 2.0 内容中正确显示的最终字符串。

public class PersianMaker
{
    // Persian character map
    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 

    }

    /// <summary>
    /// Check whether the character belongs to the Persian character list or not.
    /// </summary>
    /// <param name="ch"></param>
    /// <returns>true if the character belongs to the
    /// Persian character list; otherwise, false.</returns>
    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;
    }

    /// <summary>
    /// Check whether the character is from NoLastAppend group or not.
    /// </summary>
    /// <param name="ch"></param>
    /// <returns>true if the character is from NoLastAppend group;
    /// otherwise, false.</returns>
    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;
    }

    /// <summary>
    /// Generates a correct Persian text to be presented
    /// in the silverlight context.
    /// </summary>
    /// <param name="text"></param>
    /// <returns>Persian correct format of the text</returns>
    private string ToPersianString(string text)
    {
        int i = 0;
        string str2 = "";
        while (i < text.Length)
        {
            ECharPossition possition= ECharPossition.StartingChar;
            // get current letter
            if (IsPersianCharacter(Convert.ToChar(text.Substring(i, 1))))
            {
                if (i == 0)// This is the first chraracter of the string
                {
                    possition = ECharPossition.StartingChar;
                }
                else if (i == (text.Length - 1))
                // This is the last character of the string
                {
                    // get letter before
                    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 // the current character is neither first nor last
                {
                    // get letter before
                    if (IsPersianCharacter(
                           Convert.ToChar(text.Substring(i - 1, 1))))
                    {
                        if (IsNoLastAppendCharacter(
                              Convert.ToChar(text.Substring(i - 1, 1))))
                        {
                            // get current letter
                            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;
                    }
                }

                // get current letter
                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;
    
                //Retreive the character set of the current letter
                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
            {
                // The character does not belong to the CharMap
                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;
    }

    /// <summary>
    /// Reverse the specified string to become right to left.
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    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
    }

}

使用代码

此项目的源代码可在此处获得

© . All rights reserved.