/// <summary> Gets or sets Character in specified form </summary> /// <param name="form">Form of persian character</param> /// <returns>Character in specified form.</returns> public char this[PersianCharacterForm form] { get { return(_Characters[(int)form]); } set { _Characters[(int)form] = value; } }
/// <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); }