Example #1
0
        /// <summary>
        /// maps each none persian chracter to equivalent persian character
        /// </summary>
        /// <param name="c">The character to remap to persian character</param>
        /// <returns>if there is a map for given character returns a PersianCharacter, otherwise null.</returns>
        public PersianCharacter GetMappedCharacter(char c)
        {
            PersianCharacter result = null;

            if (!_Map.TryGetValue(c, out result))
            {
                result = null;
            }
            return(result);
        }
Example #2
0
        private void CreateMap(PersianCharacter pc, params char[] keys)
        {
            char c = ' ';

            try
            {
                foreach (var k in keys)
                {
                    c = k;
                    _Map.Add(k, pc);
                }
            }
            catch (ArgumentException ex)
            {
                throw new ArgumentException("Key exist " + c, "keys", ex);
            }
        }
Example #3
0
        /// <summary>
        /// Convert specified text to equivalent persian text
        /// </summary>
        /// <param name="text">Text to convert</param>
        /// <returns>Converted text</returns>
        public string Convert(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(string.Empty);
            }
            else
            {
                // make sure that we alocated enough space for text
                EnsureCharSize(text.Length);

                // find maps (if exist)
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _SourceChars[i];
                    cf.SourceChar = text[i];
                    cf.Character  = CharacterMap.GetMappedCharacter(cf.SourceChar);
                    cf.Form       = PersianCharacterForm.Isolated;
                }

                // calc forms of each character
                for (int i = 0; i < text.Length; i++)
                {
                    PersianCharacter     currentPc = _SourceChars[i].Character;
                    PersianCharacter     prePc     = null;
                    PersianCharacter     nextPc    = null;
                    PersianCharacterForm form      = PersianCharacterForm.Isolated;

                    if (currentPc != null)
                    {
                        if (i > 0)
                        {
                            prePc = _SourceChars[i - 1].Character;
                        }
                        if (i < text.Length - 1)
                        {
                            nextPc = _SourceChars[i + 1].Character;
                        }

                        if (prePc == null)
                        {
                            if (nextPc != null && nextPc.CanStickToPrevious && currentPc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Initial;
                            }
                        }
                        else if (nextPc == null)
                        {
                            if (prePc != null && prePc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Final;
                            }
                        }
                        else
                        {
                            if (nextPc.CanStickToPrevious && prePc.CanStickToNext)
                            {
                                if (currentPc.CanStickToNext)
                                {
                                    form = PersianCharacterForm.Medial;
                                }
                                else
                                {
                                    form = PersianCharacterForm.Final;
                                }
                            }
                            else if (prePc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Final;
                            }
                            else if (nextPc.CanStickToPrevious && currentPc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Initial;
                            }
                        }
                    }
                    _SourceChars[i].Form = form;
                }

                // build text from end to start
                if (!RightToLeft)
                {
                    Reverse(_SourceChars, 0, text.Length - 1);

                    int invalidIndex  = -1000;
                    int firstLTRIndex = invalidIndex;

                    for (int i = 0; i < text.Length; i++)
                    {
                        CharInfo cf = _SourceChars[i];
                        if (cf.Character == null || cf.Character.LeftToRight || cf.SourceChar == ' ')
                        {
                            if (firstLTRIndex == invalidIndex && cf.SourceChar != ' ')
                            {
                                firstLTRIndex = i;
                            }
                        }
                        else
                        {
                            if (firstLTRIndex != invalidIndex)
                            {
                                int spaceCount = 0;
                                for (int k = i - 1; k >= 0; k--)
                                {
                                    if (_SourceChars[k].SourceChar == ' ')
                                    {
                                        spaceCount++;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                Reverse(_SourceChars, firstLTRIndex, i - 1 - spaceCount);
                                firstLTRIndex = invalidIndex;
                            }
                        }
                    }

                    if (firstLTRIndex != invalidIndex)
                    {
                        Reverse(_SourceChars, firstLTRIndex, text.Length - 1);
                        firstLTRIndex = invalidIndex;
                    }
                }

                StringBuilder result = new StringBuilder();
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _SourceChars[i];
                    if (cf != null && cf.Character != null)
                    {
                        result.Append(cf.Character[cf.Form]);
                    }
                    else
                    {
                        result.Append(cf.SourceChar);
                    }
                }

                if (ConvertLigature)
                {
                    foreach (var li in _Ligatures)
                    {
                        result.Replace(li.Source, li.Replace);
                    }
                }
                return(result.ToString());
            }
        }
        /// <summary>
        /// Convert specified text to equivalent persian text
        /// </summary>
        /// <param name="text">Text to convert</param>
        /// <returns>Converted text</returns>
        public string Convert(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                LastConvertedText = string.Empty;
            }
            else if (LastConvertedText != null && LastConvertedText.Equals(text, StringComparison.Ordinal))
            {
                return(LastConvertedText);
            }
            else
            {
                // make sure that we alocated enough space for text
                EnsureCharSize(text.Length);

                if (LastConvertedText == null)
                {
                    LastConvertedText = string.Empty;
                }
                int startoldIndex = 0;
                int lastoldIndex  = LastConvertedText.Length - 1;

                if (LastConvertedText.Length == text.Length + 1) // characters removed
                {
                    int index = LastConvertedText.IndexOf(text);
                    if (index >= 0)
                    {
                        if (index == 0)
                        {
                            PersianCharacter pc = CharacterMap.GetMappedCharacter(LastConvertedText[LastConvertedText.Length - 1]);
                            if (pc != null && !pc.LeftToRight)
                            {
                                // we have to remove from first because text is reversed
                                startoldIndex = LastConvertedText.Length - text.Length;
                            }
                            else
                            {
                                lastoldIndex = text.Length - 1;
                            }
                        }
                        else
                        {
                            lastoldIndex = text.Length - 1;
                        }
                        text = LastConvertedText.Substring(startoldIndex, text.Length);
                    }
                }

                bool findDiff = false;
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _SourceChars[i];
                    cf.SourceChar         = text[i];
                    cf.Character          = CharacterMap.GetMappedCharacter(cf.SourceChar);
                    cf.Form               = PersianCharacterForm.Isolated;
                    _RepositionedChars[i] = null;
                    cf.IsReversed         = false;

                    // start from begin and search for missmatch
                    if (!findDiff && startoldIndex < LastConvertedText.Length)
                    {
                        if (cf.SourceChar == LastConvertedText[startoldIndex])
                        {
                            startoldIndex++;
                            cf.IsReversed = true;
                        }
                        else
                        {
                            findDiff = true;
                        }
                    }
                }

                if (findDiff) // if we found missmatch start from last index to find last missmatch
                {
                    for (int i = text.Length - 1; i >= 0; i--)
                    {
                        CharInfo cf = _SourceChars[i];
                        if (lastoldIndex >= startoldIndex)
                        {
                            if (cf.SourceChar == LastConvertedText[lastoldIndex])
                            {
                                lastoldIndex--;
                                cf.IsReversed = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }


                // find none persian characters and place them in correct position
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _SourceChars[i];
                    if (!cf.IsReversed)
                    {
                        _RepositionedChars[text.Length - i - 1] = cf;
                    }
                }

                // place persian characters ( that we found them in previous text change) in correct position
                int j = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    if (_RepositionedChars[i] == null)
                    {
                        for (; j < text.Length; j++)
                        {
                            if (_SourceChars[j].IsReversed)
                            {
                                _RepositionedChars[i] = _SourceChars[j];
                                j++;
                                break;
                            }
                        }
                    }
                }

                // place Left To Right characters to correct place

                // find one left to right character
                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _RepositionedChars[i];
                    if (!cf.IsReversed && (cf.Character == null || cf.Character.LeftToRight))
                    {
                        // find surrounding ltf chars
                        int startIndex = i;
                        int endIndex   = i;

                        //find most previous valid ltf index
                        for (int k = i - 1; k >= 0; k--)
                        {
                            CharInfo cf2 = _RepositionedChars[k];
                            if (cf2.IsReversed && (cf2.Character == null || cf2.Character.LeftToRight))
                            {
                                startIndex = k;
                            }
                            else
                            {
                                break;
                            }
                        }

                        //find most next valid ltf index
                        for (int k = i + 1; k < text.Length; k++)
                        {
                            CharInfo cf2 = _RepositionedChars[k];
                            if (cf2.IsReversed && (cf2.Character == null || cf2.Character.LeftToRight))
                            {
                                endIndex = k;
                            }
                            else
                            {
                                break;
                            }
                        }

                        int index = endIndex - (i - startIndex);
                        int sign  = Math.Sign(index - i);

                        for (int k = i; k != index; k += sign)
                        {
                            _RepositionedChars[k] = _RepositionedChars[k + sign];
                        }

                        _RepositionedChars[index] = cf;
                        cf.IsReversed             = true;
                    }
                }

                // calc forms of each character
                for (int i = 0; i < text.Length; i++)
                {
                    PersianCharacter     currentPc = _RepositionedChars[i].Character;
                    PersianCharacter     prePc     = null;
                    PersianCharacter     nextPc    = null;
                    PersianCharacterForm form      = PersianCharacterForm.Isolated;

                    if (currentPc != null)
                    {
                        if (i > 0)
                        {
                            nextPc = _RepositionedChars[i - 1].Character;
                        }
                        if (i < text.Length - 1)
                        {
                            prePc = _RepositionedChars[i + 1].Character;
                        }

                        if (prePc == null)
                        {
                            if (nextPc != null && nextPc.CanStickToPrevious && currentPc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Initial;
                            }
                        }
                        else if (nextPc == null)
                        {
                            if (prePc != null && prePc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Final;
                            }
                        }
                        else
                        {
                            if (nextPc.CanStickToPrevious && prePc.CanStickToNext)
                            {
                                if (currentPc.CanStickToNext)
                                {
                                    form = PersianCharacterForm.Medial;
                                }
                                else
                                {
                                    form = PersianCharacterForm.Final;
                                }
                            }
                            else if (prePc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Final;
                            }
                            else if (nextPc.CanStickToPrevious && currentPc.CanStickToNext)
                            {
                                form = PersianCharacterForm.Initial;
                            }
                        }
                    }
                    _RepositionedChars[i].Form = form;
                }

                // build text from end to start
                StringBuilder result = new StringBuilder();

                for (int i = 0; i < text.Length; i++)
                {
                    CharInfo cf = _RepositionedChars[i];
                    if (cf.Character != null)
                    {
                        result.Append(cf.Character[cf.Form]);
                    }
                    else
                    {
                        result.Append(cf.SourceChar);
                    }
                }

                if (ConvertLigature)
                {
                    result.Replace("\uFE8E\uFEDF", "\uFEFB");
                    result.Replace("\uFE8E\uFEE0", "\uFEFC");
                    result.Replace("\uFEEA\uFEE0\uFEDF\uFE8D", "\uFDF2");
                }
                LastConvertedText = result.ToString();
            }
            return(LastConvertedText);
        }