|
Does any know of a commercial product that provides Arabic support for WINCE.NET ?
Thanks
Hussein Dharsi
CIO
ADB
Dubai
|
|
|
|
|
www.imaginet-software.com
For Pocketpc's
|
|
|
|
|
Hello
I would like to thank you very much for this article. Which has been very helpful to me. Since my applicatin is in C# I had to migrate your code. I also made some optimizations, handling lam alef, etc. Please find my code below.
using System;
using System.Data;
using System.Text;
namespace GNS.Mobility.Utilities
{
public sealed class Arabization
{
static Arabization()
{
arabicArray = new int[lookupArray.Length];
for(int i = 0; i < lookupArray.GetLength(0); i++)
{
for(int j = 0; j < lookupArray.GetLength(1); j++)
{
arabicArray[i * lookupArray.GetLength(1) + j] = lookupArray[i, j];
}
}
QuickSort(arabicArray, 0, arabicArray.Length -1);
arabicSearchStart = 0;
while(arabicArray[arabicSearchStart] == 0)
arabicSearchStart++;
}
private Arabization()
{
}
private static void QuickSort(int[] array, int left, int right)
{
do
{
int i = left;
int j = right;
int x = array[(i + j) >> 1];
do
{
while(array[i] < x) i++;
while(x < array[j]) j--;
if (i > j) break;
if (i < j)
{
int val = array[i];
array[i] = array[j];
array[j] = val;
}
i++;
j--;
}
while (i <= j);
if (j - left <= right - i)
{
if (left < j) QuickSort(array, left, j);
left = i;
}
else
{
if (i < right) QuickSort(array, i, right);
right = j;
}
}
while (left < right);
}
private static int BinarySearch(int[] array, int val)
{
int u, l, m, a;
l = array == arabicArray ? arabicSearchStart : 0;
u = array.Length - 1;
while(l <= u)
{
m = (l + u) >> 1;
a = array[m];
if(a == val)
{
return m;
}
else if(a < val)
{
l = m + 1;
}
else
u = m - 1;
}
return ~l;
}
private const int endIdx = 1;
private const int iniIdx = 2;
private const int midIdx = 3;
private const int isoIdx = 4;
private static readonly int[] arabicArray;
private static readonly int arabicSearchStart;
private static readonly int[,] lamalefarray =
{
{0x622, 0xfef6, 0xfef5, 0xfef6, 0xfef5},
{0x623, 0xfef8, 0xfef7, 0xfef8, 0xfef7},
{0x625, 0xfefa, 0xfef9, 0xfefa, 0xfef9},
{0x627, 0xfefc, 0xfefb, 0xfefc, 0xfefb},
};
private static readonly int[,] lookupArray =
{
{0x621, 0xfe80, 0xfe80, 0xfe80, 0xfe80},
{0x622, 0xfe82, 0xfe81, 0xfe82, 0xfe81},
{0x623, 0xfe84, 0xfe83, 0xfe84, 0xfe83},
{0x624, 0xfe86, 0xfe85, 0xfe86, 0xfe85},
{0x625, 0xfe88, 0xfe87, 0xfe88, 0xfe87},
{0x626, 0xfe8a, 0xfe8b, 0xfe8c, 0xfe89},
{0x627, 0xfe8e, 0xfe8d, 0xfe8e, 0xfe8d},
{0x628, 0xfe90, 0xfe91, 0xfe92, 0xfe8f},
{0x629, 0xfe94, 0xfe93, 0xfe93, 0xfe93},
{0x62a, 0xfe96, 0xfe97, 0xfe98, 0xfe95},
{0x62b, 0xfe9a, 0xfe9b, 0xfe9c, 0xfe99},
{0x62c, 0xfe9e, 0xfe9f, 0xfea0, 0xfe9d},
{0x62d, 0xfea2, 0xfea3, 0xfea4, 0xfea1},
{0x62e, 0xfea6, 0xfea7, 0xfea8, 0xfea5},
{0x62f, 0xfeaa, 0xfea9, 0xfeaa, 0xfea9},
{0x630, 0xfeac, 0xfeab, 0xfeac, 0xfeab},
{0x631, 0xfeae, 0xfead, 0xfeae, 0xfead},
{0x632, 0xfeb0, 0xfeaf, 0xfeb0, 0xfeaf},
{0x633, 0xfeb2, 0xfeb3, 0xfeb4, 0xfeb1},
{0x634, 0xfeb6, 0xfeb7, 0xfeb8, 0xfeb5},
{0x635, 0xfeba, 0xfebb, 0xfebc, 0xfeb9},
{0x636, 0xfebe, 0xfebf, 0xfec0, 0xfebd},
{0x637, 0xfec2, 0xfec3, 0xfec4, 0xfec1},
{0x638, 0xfec6, 0xfec7, 0xfec8, 0xfec5},
{0x639, 0xfeca, 0xfecb, 0xfecc, 0xfec9},
{0x63a, 0xfece, 0xfecf, 0xfed0, 0xfecd},
{0x63b, 0, 0, 0, 0},
{0x63c, 0, 0, 0, 0},
{0x63d, 0, 0, 0, 0},
{0x63e, 0, 0, 0, 0},
{0x63f, 0, 0, 0, 0},
{0x640, 0x0640, 0x0640, 0x0640, 0x0640},
{0x641, 0xfed2, 0xfed3, 0xfed4, 0xfed1},
{0x642, 0xfed6, 0xfed7, 0xfed8, 0xfed5},
{0x643, 0xfeda, 0xfedb, 0xfedc, 0xfed9},
{0x644, 0xfede, 0xfedf, 0xfee0, 0xfedd},
{0x645, 0xfee2, 0xfee3, 0xfee4, 0xfee1},
{0x646, 0xfee6, 0xfee7, 0xfee8, 0xfee5},
{0x647, 0xfeea, 0xfeeb, 0xfeec, 0xfee9},
{0x648, 0xfeee, 0xfeed, 0xfeee, 0xfeed},
{0x649, 0xfef0, 0xfeef, 0xfef0, 0xfeef},
{0x64a, 0xfef2, 0xfef3, 0xfef4, 0xfef1},
{0x64b, 0, 0, 0, 0},
{0x64c, 0, 0, 0, 0},
{0x64d, 0, 0, 0, 0},
{0x64e, 0, 0, 0, 0},
{0x64f, 0, 0, 0, 0},
{0x650, 0, 0, 0, 0},
{0x651, 0, 0, 0, 0},
{0x652, 0, 0, 0, 0},
};
private const int lamUnicode = 0x644;
private static readonly int[] set1 =
{
0x626, 0x628, 0x62a, 0x62b, 0x62c, 0x62d, 0x62e, 0x633,
0x634, 0x635, 0x636, 0x637, 0x638, 0x639, 0x63a, 0x640,
0x641, 0x642, 0x643, 0x644, 0x645, 0x646, 0x647, 0x64a
};
private static readonly int[] set2 =
{
0x622, 0x623, 0x624, 0x625, 0x627, 0x629, 0x62f, 0x630,
0x631, 0x632, 0x648, 0x649
};
private static bool IsArabic(char ch)
{
int ch1 = ch;
if((((ch1 & 0xff00) ^ 0x0600) != 0) && (((ch1 & 0xff00) ^ 0xfe00) != 0))
return false;
return BinarySearch(arabicArray, ch1) >= 0;
}
private static bool IsGenericArabic(char ch)
{
int ch1 = (int)ch;
return ch1 >= 0x0621 && ch1 <= 0x064a;
}
private static bool IsInSet1(char ch)
{
return BinarySearch(set1, (int)ch) >= 0;
}
private static bool IsInSet2(char ch)
{
return BinarySearch(set2, (int)ch) >= 0;
}
private static void StringReverse(StringBuilder input, int index, int length)
{
for(int i = 0; i < length; i++)
{
int revind = length - i - 1;
if(revind <= i)
return;
char temp = input[index + revind];
input[index + revind] = input[i + index];
input[i + index] = temp;
}
}
private static void StringReverse(StringBuilder input)
{
StringReverse(input, 0, input.Length);
}
private static void ArabicReverse(StringBuilder input)
{
StringReverse(input);
for(int i = 0; i < input.Length; i++)
{
if(!IsArabic(input[i]))
{
int len = 0;
while(((i + len) < input.Length) && !IsArabic(input[i + len]))
{
len++;
}
StringReverse(input, i, len);
i += len - 1;
}
}
}
public static string Arabize(string input)
{
bool linkBefore, linkAfter;
StringBuilder sbout = new StringBuilder(input);
for(int i = 0, k = 0; i < input.Length; i++, k++)
{
char ch = input[i];
int idx = (int)ch - lookupArray[0, 0];
if(idx >= 0 && idx < lookupArray.GetLength(0))
{
if(i == (input.Length - 1))
linkAfter = false;
else
linkAfter = IsInSet1(input[i + 1]) || IsInSet2(input[i + 1]);
if(i == 0)
linkBefore = false;
else
linkBefore = IsInSet1(input[i - 1]);
if(linkAfter && (int)ch == lamUnicode)
{
char ch1 = input[i + 1];
int j;
for(j = 0; j < lamalefarray.GetLength(0); j++)
{
if((int)ch1 == lamalefarray[j, 0])
{
sbout[k] = (char)lamalefarray[j, linkBefore ? midIdx : iniIdx];
sbout.Remove(k + 1, 1);
i++;
break;
}
}
if(j < lamalefarray.GetLength(0))
continue;
}
if(linkAfter && linkBefore)
sbout[k] = (char)lookupArray[idx, midIdx];
else if(linkBefore && !linkAfter)
sbout[k] = (char)lookupArray[idx, endIdx];
else if(!linkBefore && linkAfter)
sbout[k] = (char)lookupArray[idx, iniIdx];
else if(!linkBefore && !linkAfter)
sbout[k] = (char)lookupArray[idx, isoIdx];
if((int)sbout[k] == 0)
{
sbout.Remove(k, 1);
}
}
else if(IsArabic(ch))
return input;
}
ArabicReverse(sbout);
return sbout.ToString();
}
}
}
|
|
|
|
|
Hi Mr. Sherif ELMetainy,
First of all, i would like to thank you for your Arabization Code in C#,i used it in my project on WIN CE terminals,but now i have a serious problem with this code,the problem is that i create a test program to read from a text file contains id numbers and the description related to these id numbers,the description is written in arabic characters,now in my program i use the binary search algorithm,to search in that text file based on the id number and then display its description,but i notice that the Arabization Code read from the text file when it is saved as Unicode Encoding,but when that text file is saved in ANSI Encoding,nothing dispaly,my problem is that i cannot find the required equations to search under text file saved in unicode encoding using the binary search,by the way you can notice that the arabization Code written in VC++,is read from ANSI text file,so can you help how i can change in your code to make it read from ANSI text file?.
Thanks in Advance.
Looking forward to hearing from you .
TTALAL
|
|
|
|
|
Could you find a solution for that? I have a problem that:
1. I have a file that has English & Arabic text readable on Windows.
2. I thought of opening the text file and displaying the Arabic text using the above arabizer class - it displayed garbagge.
3. If i install the Imaginet Arabizer on the winCE HH I can view this text file very well from the pocket memo
4. If i simply open that file and try to read text from it, (with Arabizer installed) it reads rubbish!!!!!!!!!!!!!!!!!!
I guess it has to do with how we open the file and read from it.
I need help on that matter URGENTLY.
|
|
|
|
|
Here is a C# version:
public class StringReverse
{
public class GlyphMap
{
public char character;
public char endGlyph;
public char iniGlyph;
public char midGlyph;
public char isoGlyph;
public GlyphMap(int c, int e, int i, int m, int iso)
{
character = (char)c;
endGlyph = (char)e;
iniGlyph = (char)i;
midGlyph = (char)m;
isoGlyph = (char)iso;
}
public GlyphMap(char c, char e, char i, char m, char iso)
{
character = c;
endGlyph = e;
iniGlyph = i;
midGlyph = m;
isoGlyph = iso;
}
}
private static GlyphMap[] a = new GlyphMap[] {
new GlyphMap(0x630, 0xfeac, 0xfeab, 0xfeac, 0xfeab),
new GlyphMap(0x62f, 0xfeaa, 0xfea9, 0xfeaa, 0xfea9),
new GlyphMap(0x62c, 0xfe9e, 0xfe9f, 0xfea0, 0xfe9d),
new GlyphMap(0x62d, 0xfea2, 0xfea3, 0xfea4, 0xfea1),
new GlyphMap(0x62e, 0xfea6, 0xfea7, 0xfea8, 0xfea5),
new GlyphMap(0x647, 0xfeea, 0xfeeb, 0xfeec, 0xfee9),
new GlyphMap(0x639, 0xfeca, 0xfecb, 0xfecc, 0xfec9),
new GlyphMap(0x63a, 0xfece, 0xfecf, 0xfed0, 0xfecd),
new GlyphMap(0x641, 0xfed2, 0xfed3, 0xfed4, 0xfed1),
new GlyphMap(0x642, 0xfed6, 0xfed7, 0xfed8, 0xfed5),
new GlyphMap(0x62b, 0xfe9a, 0xfe9b, 0xfe9c, 0xfe99),
new GlyphMap(0x635, 0xfeba, 0xfebb, 0xfebc, 0xfeb9),
new GlyphMap(0x636, 0xfebe, 0xfebf, 0xfec0, 0xfebd),
new GlyphMap(0x637, 0xfec2, 0xfec3, 0xfec4, 0xfec1),
new GlyphMap(0x643, 0xfeda, 0xfedb, 0xfedc, 0xfed9),
new GlyphMap(0x645, 0xfee2, 0xfee3, 0xfee4, 0xfee1),
new GlyphMap(0x646, 0xfee6, 0xfee7, 0xfee8, 0xfee5),
new GlyphMap(0x62a, 0xfe96, 0xfe97, 0xfe98, 0xfe95),
new GlyphMap(0x627, 0xfe8e, 0xfe8d, 0xfe8e, 0xfe8d),
new GlyphMap(0x644, 0xfede, 0xfedf, 0xfee0, 0xfedd),
new GlyphMap(0x628, 0xfe90, 0xfe91, 0xfe92, 0xfe8f),
new GlyphMap(0x64a, 0xfef2, 0xfef3, 0xfef4, 0xfef1),
new GlyphMap(0x633, 0xfeb2, 0xfeb3, 0xfeb4, 0xfeb1),
new GlyphMap(0x634, 0xfeb6, 0xfeb7, 0xfeb8, 0xfeb5),
new GlyphMap(0x638, 0xfec6, 0xfec7, 0xfec8, 0xfec5),
new GlyphMap(0x632, 0xfeb0, 0xfeaf, 0xfeb0, 0xfeaf),
new GlyphMap(0x648, 0xfeee, 0xfeed, 0xfeee, 0xfeed),
new GlyphMap(0x629, 0xfe94, 0xfe93, 0xfe93, 0xfe93),
new GlyphMap(0x649, 0xfef0, 0xfeef, 0xfef0, 0xfeef),
new GlyphMap(0x631, 0xfeae, 0xfead, 0xfeae, 0xfead),
new GlyphMap(0x624, 0xfe86, 0xfe85, 0xfe86, 0xfe85),
new GlyphMap(0x621, 0xfe80, 0xfe80, 0xfe80, 0xfe7f),
new GlyphMap(0x626, 0xfe8a, 0xfe8b, 0xfe8c, 0xfe89),
new GlyphMap(0x623, 0xfe84, 0xfe83, 0xfe84, 0xfe83),
new GlyphMap(0x622, 0xfe82, 0xfe81, 0xfe82, 0xfe81),
new GlyphMap(0x625, 0xfe88, 0xfe87, 0xfe88, 0xfe87)
};
public static string FullArabicReverse(string s)
{
bool linkBefore, linkAfter;
string result;
result = s;
for (int i = 0; i < s.Length; i++)
{
char ch = s[i];
if ((ch >= 0x0621 && ch <= 0x064a))
{
int idx = 0;
while (idx < a.Length)
{
if (a[idx].character == s[i])
break;
++idx;
}
if (i == s.Length - 1)
linkAfter = false;
else
linkAfter = (isFromTheSet1(s[i + 1]) ||
isFromTheSet2(s[i + 1]));
if (i == 0)
linkBefore = false;
else
linkBefore = isFromTheSet1(s[i - 1]);
if (linkBefore && linkAfter)
setAt(result, i, a[idx].midGlyph);
if (linkBefore && !linkAfter)
setAt(result, i, a[idx].endGlyph);
if (!linkBefore && linkAfter)
setAt(result, i, a[idx].iniGlyph);
if (!linkBefore && !linkAfter)
setAt(result, i, a[idx].isoGlyph);
}
}
result = BaseArabicReverse(result);
return result;
}
public static string setAt(string s, int position, char newValue)
{
if (s.Length > position)
{
return s.Substring(0, position) + newValue + s.Substring(position + 1);
}
else
{
return s;
}
}
private static bool isFromTheSet1(char ch)
{
char[] theSet1 = new char[22] {
(char)0x62c, (char)0x62d, (char)0x62e, (char)0x647, (char)0x639, (char)0x63a, (char)0x641, (char)0x642,
(char)0x62b, (char)0x635, (char)0x636, (char)0x637, (char)0x643, (char)0x645, (char)0x646, (char)0x62a,
(char)0x644, (char)0x628, (char)0x64a, (char)0x633, (char)0x634, (char)0x638};
int i = 0;
while (i < theSet1.Length)
{
if (ch == theSet1[i])
return true;
++i;
}
return false;
}
private static bool isFromTheSet2(char ch)
{
char[] theSet2 = new char[12] {
(char)0x627, (char)0x623, (char)0x625, (char)0x622, (char)0x62f, (char)0x630, (char)0x631, (char)0x632,
(char)0x648, (char)0x624, (char)0x629, (char)0x649};
int i = 0;
while (i < theSet2.Length)
{
if (ch == theSet2[i])
return true;
++i;
}
return false;
}
public static string BaseArabicReverse(string s)
{
string result = "";
string rev = "";
s = new String(s.ToCharArray().Reverse<char>().ToArray<char>());
int i = 0;
while (i < s.Length)
{
if ((s[i] >= '0' && s[i] <= '9'))
{
rev = "";
while ((s[i] >= '0' && s[i] <= '9'))
{
rev = rev + s[i];
++i;
}
rev = new String(rev.ToCharArray().Reverse<char>().ToArray<char>());
result = result + rev;
}
else
{
result = result + s[i];
++i;
}
}
return result;
}
}
|
|
|
|
|
Dear Mr. Sherif ElMetainy
Can you please help me ,what is the following piece of your arabization code means and what are the unicode values refer to?
private static bool IsArabic(char ch)
{
int ch1 = ch;
if((((ch1 & 0xff00) ^ 0x0600) != 0) && (((ch1 & 0xff00) ^ 0xfe00) != 0)) return false;
return BinarySearch(arabicArray, ch1) >= 0;
}
|
|
|
|
|
Thanks alot for this code
but after using this code i still have a problem in lam alef characters the code separate characters before and after this character
please help me
thanks alot again for this code
Heba El-faid
|
|
|
|
|
Hi
I want to show quran words on my pocket pc, but don't show tashkeel character.
I want to show quran with tashkeel character.
for example : ?????? ??????? ??????????? ??????????
but this word have got tashkeel character and show seperated.
please help me
and send me answer with my mail!!
please
muratmetin@gmail.com
|
|
|
|
|
Hi,It's really perfect!
Shall you give me a hand...
Could you add some Testing class,'*.ttf','*.txt(with content of some unicode spec char)'
Really Thanks very much!
|
|
|
|
|
Hi, I read your article, and it is very intresting for me because I just started programing my first arabic PocketPC 2003 software.
BUT I wonder if there is any way to Modify the Windows Mobile 2003 to support Arabic?
I mean that when I'm programing an application I can make the interface arabic, BUT if I'm using an alrady made application like Work & Excel & SMS, How could I make them support Arabic?
Thanks very much for any help
Fadi
|
|
|
|
|
Asalamu 'Alaikum
I've the same problem..
I've heard about "arabizeIT" (I think it's free ,try freewareppc.com) but I didn't test it yet..
I think "Imaginet-software" has the best solution but it's expensive to me..
please if anyone has an arabic input tool(keyboard, recognizer..) pls just reply...
Zaher
|
|
|
|
|
Hi Mr. Mohamed Abdel-Monem
Thanks for your very useful article .
I want to develop an arabic Windows CE based application in my graduation project and I need your help .
* I don't have a pocket pc device. I am developping using visual studio 2003 .Net in my work and using its pocket pc emulator.
SO, My question is :
- How can I load and use arabic font and make the emulator understanding its arabic chars ?
Please help me as quickly as possible ...
Thanks for your time ...
Alaa El-Din Moustafa Ali
Faculty of Computers and Information
Cairo University
|
|
|
|
|
Although, It is too late, you will be passed out by now. Still, let me express. Use Active Sync or enable network and then use some shared folder on your computer to copy fonts cab file to the PPC emulator. Once copied, intall it you will have the font
|
|
|
|
|
our char didnt into arabize func and i want to run this code in C# how could i do it. can u help me ?
|
|
|
|
|
I've copied over Tahoma.ttf and Tahomabd.ttf from my windows machine to my emulator's windows directory. But how do i find out if my emulator or PDA has the ARABIC_CHARSET installed, and if it doesn't how would I go about installing it?
Thanks in advance.
|
|
|
|
|
Hi..
If you used this code, you should not be worried about ARABIC_CHARSET. The only thing you have to do is copying font files and restarting the PDA
|
|
|
|
|
Hi
I tried to copy the Tahoma.ttf & Tahomab.ttf to the windows directory but I get an error message " Write protect or file in use"
Did you get the same problem with the emulator ?!? and how did you resolve it?
Thanks
|
|
|
|
|
Hi Mohamed,
Is there a way to use this same code in eVB or .NET CF (using Visual Studio .NET) ?? (
Any help would be highly appreciated! ...
Thank you for your time in advance,
Kayo.
|
|
|
|
|
You can compile and link this code as a dynamic link library or you have to convert this code into VB. Contact me if you still don't know how to fix it. You will be welcome
|
|
|
|
|
Thanks Monem,
I compiled the code in eVC and made it into a DLL. The code works great!. Thank you for your effort and time to help out and in developing this code !
Best Regards
Kayo.
|
|
|
|
|
Hi I tried the same thing BUT I Had some problem...
So what kind of DLL did you make ? is it CE MFC Dll ?
And how you call it from the .NetCF ?
Is it possible to send me the source of the dll ?
Thanks
Fadi
|
|
|
|
|
please send me your dll my email adres
can I use your dll for my c# solutions?
please!!!
muratmetin@gmail.com
|
|
|
|
|
please send me your dll my email adres
can I use your dll for my c# solutions?
please!!!
vzsoft@walla.com
|
|
|
|
|
please send me your dll my email adres
jemal.houssem@gmail.com
Thks
|
|
|
|
|