'아랍어'에 해당되는 글 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 왜 이따구야 ㅠ.ㅠ
신고

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

유니코드 아랍어 오토마타  (8) 2009.03.05
아랍어 조합 방법 - unicode  (5) 2008.11.16
Posted by 구차니

댓글을 달아 주세요

  1. 비밀댓글입니다

    2015.06.08 21:14 [ ADDR : EDIT/ DEL : REPLY ]
    • 아니오 ㅠㅠ
      텔레텍스트는 해보지 않았습니다. 그리고 페르시아어도 해보지 않았고
      아랍어만 해봤습니다.(메시지 id 기반으로 다국어지원)

      2015.06.08 22:08 신고 [ ADDR : EDIT/ DEL ]
  2. ssonacy

    정말루 감사합니다. 지금 하고 있는 프로젝트에서 아랍 출력에 대한 이슈가 있었는데

    제공해 주신 코드로 해결되었습니다. 정말루 감사합니다.

    2015.09.13 01:56 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 도움이 되었다니 뿌듯하네요 ^^
      다만.. 이녀석이 줄 바꿈에 대해서는 처리가 안되니 주의하시기 바랍니다.

      2015.09.14 08:53 신고 [ ADDR : EDIT/ DEL ]
  3. 비밀댓글입니다

    2016.04.27 20:03 [ ADDR : EDIT/ DEL : REPLY ]
    • IME 연관인가요?
      입력쪽은 제가 안해봐서... 하나하나 입력이 아닌
      문장을 출력용으로 변환하는 오토마타라.. OSD 키보드에는 한번 입력할때 마다 전체 문장에 대해서 적용해 보시면 어떨까 합니다.

      2016.04.27 22:31 신고 [ ADDR : EDIT/ DEL ]
  4. 감사합니다.

    너무너무 감사합니다.
    테스트를 해보도록 하겠습니다.

    2016.04.28 09:58 신고 [ ADDR : EDIT/ DEL : REPLY ]

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

클릭만 했을 때

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

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

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

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

댓글을 달아 주세요

  1. 아..아랍어라... 지렁이 문자.
    사회시간에 배우셨겠지만 터키에서도 아랍문자를 사용했었지요.
    그런데 이말이 왜나온거지...

    어쨋든 마소는 제가 입사할 곳입니다. 껠껠껠... ㅠ

    2009.02.27 11:24 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 아랍어 조합기를 만들다 보니
      의외로 아랍어랑 한글이랑 조합의 유사성이 느껴지더라구요 ㅎ
      조만간 소스를 정리해서 공개할 예정이랍니다 ㅋ


      그리고 MS는 개띠는 안되요.
      말띠와 소띠만 된다는 소문이(응?)

      2009.02.27 11:27 신고 [ ADDR : EDIT/ DEL ]
    • 오옷! 대단한걸 만드시고 계시네요.
      기대됩니다. ㅋㅋ

      마소는 馬牛인 겝니까 ㅋㅋㅋ

      2009.02.27 12:59 신고 [ ADDR : EDIT/ DEL ]
    • 이미 만들어져 있고, 공개할정도로 코드가 깔끔하지 않아서 정리가 조금 필요 하답니다.
      급조하다 보니 무거워서 말이죠 ㅎ


      마소는 그 마소 맞습니다 맞고요~

      2009.02.27 13:22 신고 [ ADDR : EDIT/ DEL ]

아랍어의 특징

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

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

그리고 삭제시에도 백스페이스와 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
아랍어 조합 방법 - unicode  (5) 2008.11.16
Posted by 구차니

댓글을 달아 주세요

  1. 비밀댓글입니다

    2009.09.05 18:14 [ ADDR : EDIT/ DEL : REPLY ]
  2. 비밀댓글입니다

    2009.09.05 18:14 [ ADDR : EDIT/ DEL : REPLY ]
  3. 휴ㅗㅅ러ㅛㅑ

    2009.09.05 18:15 신고 [ ADDR : EDIT/ DEL : REPLY ]
  4. 비밀댓글입니다

    2013.11.19 11:24 [ ADDR : EDIT/ DEL : REPLY ]
    • 제가 아랍어를 모르는 상황에서 오토마타를 만들어서 확실히 저게 어떤 문자인지 모르겠으나

      일반적인 규칙으로는
      0x0644 0x0627의 경우
      처음과 끝으로 변환해서 0xFEDF 0xFE8E로 변환되어야 하나
      엑셀이나 워드에서 확인해보면 조금은 뜬금없지만 0xFEFB로 변환이 되더군요.

      아랍어를 아시는분이 있으면 물어보고 싶으나.. 지인중에 아랍어 쪽이 없으셔서 확인을 못한 부분이라
      조합시 변형되는 특이형태라 "예외사항"으로 표기를 한것입니다.

      2013.11.19 11:37 신고 [ ADDR : EDIT/ DEL ]