'아랍어'에 해당되는 글 3건

  1. 2009.03.05 유니코드 아랍어 오토마타 8
  2. 2009.02.26 Excel의 농간에 당하다 4
  3. 2008.11.16 아랍어 조합 방법 - unicode 5
typedef unsigned char		u8;
typedef unsigned short		u16;

#define ARABIC_SIN 0
#define ARABIC_END 1
#define ARABIC_1ST 2
#define ARABIC_MID 3

u16 ArabicEncode(u16 *arab, u8 pos, BOOL* stepit, BOOL* is2set)
{
    u16 ucode = 0;
    BOOL nowChar = FALSE;
    switch(*arab)
    {
        // 2개일 경우
        case 0x0622: ucode = 0xFE81; nowChar = TRUE; break;
        case 0x0623: ucode = 0xFE83; nowChar = TRUE; break;
        case 0x0624: ucode = 0xFE85; nowChar = TRUE; break;
        case 0x0625: ucode = 0xFE87; nowChar = TRUE; break;
        case 0x0627: ucode = 0xFE8D; nowChar = TRUE; break;
        case 0x0629: ucode = 0xFE93; nowChar = TRUE; break;
        case 0x062F: ucode = 0xFEA9; nowChar = TRUE; break;
        case 0x0630: ucode = 0xFEAB; nowChar = TRUE; break;
        case 0x0631: ucode = 0xFEAD; nowChar = TRUE; break;
        case 0x0632: ucode = 0xFEAF; nowChar = TRUE; break;
        case 0x0648: ucode = 0xFEED; nowChar = TRUE; break;
        case 0x0649: ucode = 0xFEEF; nowChar = TRUE; break;

        // 4개 일경우
        case 0x0626: ucode = 0xFE89; nowChar = FALSE; break;
        case 0x0628: ucode = 0xFE8F; nowChar = FALSE; break;
        case 0x062A: ucode = 0xFE95; nowChar = FALSE; break;
        case 0x062B: ucode = 0xFE99; nowChar = FALSE; break;
        case 0x062C: ucode = 0xFE9D; nowChar = FALSE; break;
        case 0x062D: ucode = 0xFEA1; nowChar = FALSE; break;
        case 0x062E: ucode = 0xFEA5; nowChar = FALSE; break;
        case 0x0633: ucode = 0xFEB1; nowChar = FALSE; break;
        case 0x0634: ucode = 0xFEB5; nowChar = FALSE; break;
        case 0x0635: ucode = 0xFEB9; nowChar = FALSE; break;
        case 0x0636: ucode = 0xFEBD; nowChar = FALSE; break;
        case 0x0637: ucode = 0xFEC1; nowChar = FALSE; break;
        case 0x0638: ucode = 0xFEC5; nowChar = FALSE; break;
        case 0x0639: ucode = 0xFEC9; nowChar = FALSE; break;
        case 0x063A: ucode = 0xFECD; nowChar = FALSE; break;
        case 0x0641: ucode = 0xFED1; nowChar = FALSE; break;
        case 0x0642: ucode = 0xFED5; nowChar = FALSE; break;
        case 0x0643: ucode = 0xFED9; nowChar = FALSE; break;
        case 0x0644: ucode = 0xFEDD; nowChar = FALSE; break;
        case 0x0645: ucode = 0xFEE1; nowChar = FALSE; break;
        case 0x0646: ucode = 0xFEE5; nowChar = FALSE; break;
        case 0x0647: ucode = 0xFEE9; nowChar = FALSE; break;
        case 0x064A: ucode = 0xFEF1; nowChar = FALSE; break;
    }

    if((*arab == 0x0644) && (pos != ARABIC_END) && (pos != ARABIC_SIN))
    {
        switch(*(arab+1))
        {
            case 0x0622: ucode = 0xFEF5; *stepit = TRUE; break;
            case 0x0623: ucode = 0xFEF7; *stepit = TRUE; break;
            case 0x0625: ucode = 0xFEF9; *stepit = TRUE; break;
            case 0x0627: ucode = 0xFEFB; *stepit = TRUE; break;
            default: break;
        }

        if(*stepit == TRUE)
        {
            switch(pos)
            {
                case ARABIC_1ST:
                    if(*(arab+2) == 0x0020) break;
                    else { ucode += 0x001; break; }
                case ARABIC_MID:
                    if(*is2set == TRUE) break;
                    else { ucode += 0x001; break; }
            }

            *is2set = nowChar;
            return ucode;
        }
    }

    switch(pos)
    {
        //case ARABIC_SIN: return ucode;
        case ARABIC_1ST:
                if(nowChar == TRUE) ucode = *arab;
                else ucode += ARABIC_1ST;
                break;
        case ARABIC_MID:
                if(nowChar == TRUE) // 2개 짜리
                {
                    if(*is2set == TRUE) ucode = *arab;
                    else ucode += ARABIC_END;
                }
                else // 4개 짜리
                {
                    if(*is2set == TRUE) ucode += ARABIC_1ST;
                    else ucode += ARABIC_MID;
                }
                break;
        case ARABIC_END:
                if(nowChar == TRUE) // 2개 짜리
                {
                    if(*is2set == TRUE) ucode = *arab;
                    else ucode += ARABIC_END;
                }
                else // 4개 짜리
                {
                    if(*is2set == TRUE) ucode = *arab;
                    else ucode += ARABIC_END;
                }
                break;
    }

    *is2set = nowChar;
    return ucode;
}

BOOL isarabicstr(u16 *pu16String, u16 u16StrLength)
{
    u16 index = 0;
    BOOL arabic_exist = FALSE;

    for(index = 0;index < u16StrLength;index++)
    {
        if(pu16String[index] >= 0x060C && pu16String[index] <= 0x064B) return TRUE;
    }

    return arabic_exist;
}

void Arabic_automata(u16 *target_str, u16 *src_str,u16 u16Length)
{
	BOOL b8ArabSpe = FALSE;
	BOOL b8is2set = FALSE;
	u16 u16Index = 0;
	u16 u16Index2 = 0;
	u16 u16Index3 = 0;
	u16 u16offset = 0;
	u16 *temp_str = NULL;
	
	temp_str = malloc((u16Length + 1) * 2);

	for (u16Index = 0; u16Index < u16Length;)
	{
		if (src_str[u16Index] >= 0x060C && u16Index < u16Length) // arabic
		{
			u16Index2 = u16Index; // 아랍어 시작점
			while(src_str[u16Index] >= 0x060C && u16Index < u16Length ) u16Index++;
			if(u16Index - u16Index2 == 1) // 단독형
			{
				temp_str[u16Length - u16Index2 + u16offset - 1] = src_str[u16Index2];
			}
			else // 2개 이상 단어
			{
				// 첫자
				temp_str[u16Length - u16Index2 + u16offset - 1] = ArabicEncode(src_str + u16Index2, ARABIC_1ST ,&b8ArabSpe, &b8is2set);
				if(b8ArabSpe == TRUE) {++u16offset; ++u16Index2;}
				
				//중간글자
				for(u16Index3 = u16Index2 + 1; u16Index3 < u16Index - 1; u16Index3++)
				{
					if(b8ArabSpe == TRUE)
					{
						b8ArabSpe = FALSE;
						temp_str[u16Length - u16Index3 + u16offset - 1] = ArabicEncode(src_str + u16Index3, ARABIC_1ST ,&b8ArabSpe, &b8is2set);
					}
					else
						temp_str[u16Length - u16Index3 + u16offset - 1] = ArabicEncode(src_str + u16Index3, ARABIC_MID ,&b8ArabSpe, &b8is2set);
					if(b8ArabSpe == TRUE) {++u16offset; ++u16Index3;}
				}
				//마지막자
				if(u16Index - u16Index2 != 1)
				{
					if(b8ArabSpe == TRUE)
					{
						b8ArabSpe = FALSE;
						temp_str[u16Length - u16Index + u16offset] = ArabicEncode(src_str + u16Index - 1, ARABIC_1ST ,&b8ArabSpe, &b8is2set);
					}
					else
						temp_str[u16Length - u16Index + u16offset] = ArabicEncode(src_str + u16Index - 1, ARABIC_END ,&b8ArabSpe, &b8is2set);
					if(b8ArabSpe == TRUE) b8ArabSpe = FALSE;
				}
			}
		}
		else if (src_str[u16Index] == 0x0020)
		{
			u16Index2 = u16Index++;
			temp_str[u16Length - u16Index + u16offset] = src_str[u16Index - 1];
		}
		else // not arabic
		{
			u16Index2 = u16Index; // 영어 시작점
			while(src_str[u16Index] > 32 && src_str[u16Index] < 255  && u16Index < u16Length && src_str[u16Index] != 0x0020) u16Index++;
			for(u16Index3 = 0; u16Index3 < u16Index - u16Index2; u16Index3++)
			{
				temp_str[u16Length - u16Index + u16Index3 + u16offset] = src_str[u16Index2 + u16Index3];
			}
		}
	}

	if(u16offset > 0)
	{
		memcpy(target_str,temp_str + u16offset,(u16Length - u16offset) * 2);
		memset(target_str + (u16Length - u16offset),0x00,u16offset * 2);
	}
	else
	{
		memcpy(target_str,temp_str,(u16Length) * 2);
		memset(target_str + u16Length,0x00,2);
	}

	free(temp_str);
}



아놔 syntax highlighter 왜 이따구야 ㅠ.ㅠ

'모종의 음모 > 아랍어 오토마타' 카테고리의 다른 글

아랍어 조합 방법 - unicode  (5) 2008.11.16
Posted by 구차니
Microsoft/Office2009. 2. 26. 22:01
parental control 이라는 아랍문장이라도 생각이 된다(아마도? ㅋ)
아무튼 이녀석을 내가 만든 조합기로 출력을 했더니 엑셀과는 다르게 나왔다.
그런데 이거 먼가 이상하다!!!

클릭만 했을 때

F2를 눌러 문자열 편집을 눌렀을 때

아니 도대체 왜 편집모드랑 보기 모드랑 다른거야!!! 라고 외치고 있었는데, 폰트가 '맑은 고딕' 으로 되어 있었다.
그래서 혹시나 하는 마음에 아랍어 폰트가 내장 되어 있는 다른 폰트로 교체 했다.
참고로 위의 폰트는 Arial 에 포함되어 있는 글자체다.

젠장 제대로 나오잖아!!!

MS는 역시 마소라서 사람말을 제대로 이해 못했나보다
Posted by 구차니

아랍어의 특징

아랍어는 오른쪽에서 왼쪽으로 씁니다. 획 역시 오른쪽 상단에서 좌측 하단으로 이어지게 됩니다.

한글의 초성/중성/종성과는 다르지만 이전 문자에 따라서 다음 문자의 모양이 달라지는 방식입니다.

그리고 삭제시에도 백스페이스와 delete키가 반대로 적용되는 듯하게 보입니다.

 

윈도우즈 폰트

Arial
Tahoma
Times New Roman
Courier New
Microsoft Sans Serif

에 아랍어 폰트가 내장 되어 있습니다.

[출처 : http://mwultong.blogspot.com/2006/08/arabic-fonts.html]

 

아랍어 조합방법



아랍어는 단독형 /  처음형 / 가운데형 / 말끝형 총 4가지의 자소로 구성되며 일부자소에는 단독형과 말끝형 만 존재합니다.

발음은 모르겠지만.. 아무튼 아랍어 글자 하나가 네가지 형태로 사용되는 것이고,

가장 위의 0x0635(0xFEB9)가 단독형

그 아래의 0xFEBA가 말끝형

그 아래의 0xFEBB가 처음형

그 아래의 0xFEBC가 가운데형 입니다.

모양을 보시면 아시겠지만,  처음형은 오른쪽 끝이 깔끔하고

중간형은 앞뒤로 이어지는 꼬리가 달렸고

말끝형은 오른족 앞에 꼬리가 달렸습니다.

4가지 형이 다 있는 문자가 아닌 경우에는

단순하게 처음형 / 가운데형만 존재하고,

처음형으로 처음형과, 단독형

가운데형으로 가운데형과, 말끝형에 사용합니다.


그리고 번지가 두개인 이유는 앞의 0x0600 번대의 데이터만 사용하고, 0xFE00대의 데이터는

실제로 전송되는것이 아니라 문자를 조합하는데 사용하기 위한 문자코드 입니다.

위에 표시된 부분에서는 단독형의 코드만 존재하고, 앞뒤로는 다른 문자입니다.

즉, 유니코드상으로 0x0600 대의 데이터를 받아서 내부적으로 0xFE00 의 데이터로 변환하여 출력을 해주시면 되겠습니다.

 

그리고 예외 사항으로 분리 문자라는 것이 존재 합니다.

ا

د

ذ

ر

ز

و

이전 문자가 2가지 형만 있는 자소일 경우 분리문자가 되며,

(이 부분은 확실하지 않습니다. 위의 6개만인지는 좀더 확인해보고 수정하겠습니다)

분리문자일 경우에는 이어지는 다음 문자가 가운데형을 쓰는대신 처음형을 써주어야 합니다.

 

다른 예외 사항으로

두가지 문자가 조합되어 생성되는 자소 뒤에도 가운데 형을 써야 하는 경우에도 처음형을 써주어야 합니다.

 

그 실례로

ل ا

가 있으며, 두녀석이 연달아서 나타나면

이 되는것이 아니라

لا

이 됩니다.

 

 

[참고서적  : 알기쉬운 아랍어 입문 /김종도 감수/ 명지출판사, 실용아랍어 / 황의갑,한덕규 지음 / 혜안]

'모종의 음모 > 아랍어 오토마타' 카테고리의 다른 글

유니코드 아랍어 오토마타  (8) 2009.03.05
Posted by 구차니