

#include <vcl.h>
#pragma hdrstop


#include  "font.h"
#include  "file.h"
#include  "ide_library.h"

#include  "main.h" 


//[참고]{------------------------------------------------------------------
//이곳에 있는 함수들은 *.gft [글꼴파일] 을 읽어들여 해당 문자를 표시하는데
//사용된다. 실제 *.gft [글꼴파일] 을 만드는데 사용되는 함수들이 아니다.
//}------------------------------------------------------------------------


//[VAR]
//{
    //[글꼴 리소스] 를 저장한다.
    struct FONTRESOURCE  _FONT_;

    //프로그램에서 실제 사용되는 [글꼴팩] 을 가진다.
    struct FONTPACK      _font;

//}


//[FONTRESOURCE]----------------------------------------------------------------

void __fastcall FONTRESOURCE_GetHandle(struct FONTRESOURCE **rFONTRESOURCE)
{
  //[2006.09.27.수][생성!!!]{-------------
  //[글꼴 리소스] 의 handle 을 넘겨 준다.
  //}-------------------------------------

  (*rFONTRESOURCE) = &_FONT_;

  return;

}

void __fastcall FONTRESOURCE_Init(void)
{
  //[2006.09.27.수][생성!!!]{----------
  //[글꼴 리소스] 를 전부 초기화 한다.
  //}----------------------------------

  //[VAR]
  //{
      struct FONTRESOURCE  *fontresource;
  //}

  //[핸들얻기]
  //{
      FONTRESOURCE_GetHandle(&fontresource);
  //}

  //[초기화]
  //{
      //만일 buf[] 안에 내용이 있는 경우는 삭제해 주어야 한다.
      if(fontresource->buf != NULL)
      {
        delete [] fontresource->buf;

      }

      fontresource->buf        = NULL;
      fontresource->size       = 0;
      fontresource->fontcount  = 0;
      fontresource->fonthandle = NULL;

      //[글꼴이름 초기화]
      //{
          //[2010.01.26.화][추가!!!]
          if(fontresource->names != NULL)
          {
            delete [] fontresource->names;

          }

          fontresource->names = NULL;

      //}

  //}

  return;

}

void __fastcall FONTRESOURCE_Load(void)
{
  //[2006.09.27.수][생성!!!]{-------------------------------------------------
  //"font" 폴더 안의 모든 [글꼴] 을 전부 읽어서 [글꼴리소스] 에 정리한다.
  //단, "font\system\" 의 [시스템글꼴] 을 가장 먼저 읽어 들여야 한다.
  //[글꼴] 의 경로는 이미 고정적이므로 여기서 경로까지 모두 구해서 사용한다.

  //[2007.02.04.일][수정!!!]
  //[한글/기호/한자/영문] 각각의 [굵은글꼴] 을 4 개 추가한다.
  //단, (기본 글꼴 index + 4) 로 [굵은글꼴] index 가 될수 있도록 반드시
  //순서대로 배치해야 한다.
  //이는 [문법강조] 기능을 넣었는데 [예약어] 의 경우는 문자색뿐 아니라 굵기도
  //[굵은글꼴] 로 설정하는 것이 뚜렷하게 구별되 보이기 때문이다.
  //}-------------------------------------------------------------------------

  //[글꼴 리소스 구조]{----------------------------------------------------------------
  //[글꼴수] + {[글꼴0 handle] + [글꼴1 handle] + ... } + { [글꼴0] + [글꼴1] + ... }.
  //   4              4                 4                    *.gft     *.gft
  //기본적으로 여기서는 그냥 Little-Endian 으로 저장한다.
  //}----------------------------------------------------------------------------------

  //[설명]{---------------------------------------------------------------------
  //(1) : ".\font\" 안의 총 글꼴수를 구한다. (*.gft 파일의 경우만 해당한다.)
  //      ".\font\system\" 안의 글꼴의 숫자를 먼저 구해야 한다.
  //      글꼴 파일의 수를 구하면서 각각의 글꼴 파일의 크기 정보를 얻어야 한다.
  //(2) : 총 [글꼴 리소스] 크기를 구한다.
  //      이 정보를 사용하여 buf[] 를 동적으로 생성해야 한다.
  //}---------------------------------------------------------------------------

  //[VAR]
  //{
      struct FONTRESOURCE  *fontresource;

      AnsiString            font_path;
      AnsiString            system_path;

      //[*.gft load]{----------------------------------------------
      //*.gft 파일을 읽어 들여 저장할때 기록하는 위치.
      //*.gft 파일을 읽어 들일때마다 해당 *.gft 파일마다 수정된다.
      unsigned char        *gft_load_handle;
      //gft_load_handle[gft_load_count] 로 사용된다.
      int                   gft_load_count = 0;
      //}----------------------------------------------------------

      int                   total_size = 0;
      int                   file_size  = 0;
      int                   i          = 0;

      //[폴더 파일 처리]
      //{
          TStringList      *file_list = new TStringList;
          int               file_count;
      //}
  //}

  //[초기화]
  //{
      //[글꼴 리소스] 전체를 초기화 한다.
      FONTRESOURCE_Init();
  //}

  //[경로얻기]
  //{
      //--------------------------------------------------------------
      font_path   = ExtractFilePath(Application->ExeName) + "font\\";
      system_path = font_path + "system\\";
      //--------------------------------------------------------------
  //}

  //[핸들얻기]
  //{
      FONTRESOURCE_GetHandle(&fontresource);
  //}

  //[전체 파일 크기 구하기]
  //{
      //[system 폴더 처리]
      //{
          //system 폴더안의 *.gft 파일 정보를 구한다.
          FILE_Get_List_Count_inFOLDER(system_path, "gft", file_list, &file_count);

          //system 폴더 안의 *.gft 파일의 총 크기를 구한다.
          for(i = 0; i < file_count; i++)
          {
            FILE_Size(system_path + file_list->Strings[i], &file_size);
            total_size += file_size;

          }

          //[글꼴수 기록]{-----------------------
          fontresource->fontcount += file_count;
          //}------------------------------------

      //}

      //[font 폴더 처리]
      //{
          //".\font\" 안의 *.gft 파일만 읽어서 해당 파일의 크기를 구한다.
          FILE_Get_List_Count_inFOLDER(font_path, "gft", file_list, &file_count);

          //system 폴더 안의 *.gft 파일의 총 크기를 구한다.
          for(i = 0; i < file_count; i++)
          {
            FILE_Size(font_path + file_list->Strings[i], &file_size);
            total_size += file_size;

          }

          //[글꼴수 기록]{-----------------------
          fontresource->fontcount += file_count;
          //}------------------------------------

      //}

  //}

  //[글꼴이름 수집 장소 생성]
  //{
      //[2010.01.26.화][중요추가!!!]{------------------------------------------------------
      //위에서 <fontresource->fontcount> 정보를 알아야 해당 개수만큼만 동적생성가능하므로
      //이 위치에서 실제 <*.gft> [순수이름] 을 저장할 공간을 생성한다.
      //수집은 더 아래쪽에서 구체적인 부분에서 처리한다.
      //이는 [시스템글꼴] 의 경우는 반드시 지정 이름에 따라 순서가 정해져야 하기 때문이다.
      //}----------------------------------------------------------------------------------

      //fontresource->names = new struct GFTNAME [fontresource->fontcount];
      //[동적생성단위적용][2021.01.24.일][수정]
      fontresource->names = new struct GFTNAME [UnitX(1024, fontresource->fontcount)];

  //}

  //[글꼴 리소스 공간 생성]
  //{
      //------------------------------------------------------------------------------------
      //[글꼴 리소스] 의 총 크기를 구하고 해당 공간을 생성해준다.

      //[글꼴 리소스] 의 총 크기를 구한다.
      fontresource->size = //count 정보.(4byte 크기)
                           4 +
                           //[글꼴 핸들] 총 크기.(4byte 단위)
                           4 * fontresource->fontcount +
                           //포함될 [글꼴] 총 크기.
                           total_size;

      //공간 생성.
      //fontresource->buf = new unsigned char[fontresource->size];
      //[동적생성단위적용][2021.01.24.일][수정]
      fontresource->buf = new unsigned char[UnitX(1024, fontresource->size)];

      //[handle] 테이블 시작 위치 얻기.
      //count 4byte 값 바로 다음 부터 시작한다.
      fontresource->fonthandle = (unsigned int *)&(((unsigned int *)fontresource->buf)[1]);

      //처음 *gft 파일의 기록을 시작할 위치를 기록한다.
      gft_load_handle = &(fontresource->buf[ //count 정보.(4byte 크기)
                                             4 +
                                             //[글꼴 핸들] 총 크기.(4byte 단위)
                                             4 * fontresource->fontcount
                                           ]);
      //------------------------------------------------------------------------------------
  //}

  //[글꼴 리소스 조합]
  //{
      //Little-Endian 으로 저장한다.

      //[count]{--------------------------------------------------------
      //count 정보는 가장 처음 4 byte 의 정보가 된다.
      ((unsigned int *)fontresource->buf)[0] = fontresource->fontcount;
      //}---------------------------------------------------------------

      //[글꼴 파일 읽기]
      //{
          //*.gft 파일을 읽어 들이면서 해당 handle 을 [헤더] 에 기록해 주어야 한다.
          //반드시 순서대로 배치해야 한다.
          
          //[system 글꼴]
          //{
              //----------------------------------------------------
              //".\font\system\" 안의 system 글꼴을 먼저 처리한다.
              //system 글꼴은 이미 파일 이름이고 정이다.
              //"12.12.kor.d.f.gft" : 한글.
              //"12.12.sym.d.f.gft" : 기호.
              //"12.12.han.d.f.gft" : 한자.
              // "8.12.eng.d.f.gft" : 영어. (영문은 폭이 1/2 이다.)
              //----------------------------------------------------

              //[한글]-----------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "12.12.kor.d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "12.12.kor.d.f.gft", gft_load_handle, &file_size);

			  //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //[기호]-----------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "12.12.sym.d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "12.12.sym.d.f.gft", gft_load_handle, &file_size);

			  //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

			  gft_load_count++;

              //[한자]-----------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "12.12.han.d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "12.12.han.d.f.gft", gft_load_handle, &file_size);

              //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //[영어]-----------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "8.12.eng.d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "8.12.eng.d.f.gft", gft_load_handle, &file_size);

              //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //-----------------------------------------------------------------------------------------


              //[한글(굵은)]--------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "12.12.kor(b).d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "12.12.kor(b).d.f.gft", gft_load_handle, &file_size);

              //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //[기호(굵은)]--------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "12.12.sym(b).d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "12.12.sym(b).d.f.gft", gft_load_handle, &file_size);

              //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //[한자(굵은)]--------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "12.12.han(b).d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "12.12.han(b).d.f.gft", gft_load_handle, &file_size);

              //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //[영어(굵은)]--------------------------------------------------------------------------------
              //*.gft 가 저장되는 시작 위치를 기록한다.
              fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
                    STR_Assign(fontresource->names[gft_load_count].name, "8.12.eng(b).d.f.gft");

                //}

              FILE_Open_forFontResource(system_path + "8.12.eng(b).d.f.gft", gft_load_handle, &file_size);

              //[2022.09.11.일][중요수정]{************************************************************
			  //파일 포인터를 다음 *.gft 저장 위치로 수정한다.
			  //TC++2006 에서 이상 없는 코드.
			  //((unsigned int)gft_load_handle) += file_size;
			  //원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
			  gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
			  //}*************************************************************************************

              gft_load_count++;

              //--------------------------------------------------------------------------------------------
          //}

          //[font 글꼴]
          //{
              //-----------------------------------------------------------------
              //".\font\" 안의 *.gft [글꼴파일] 을 읽어 들인다.
              //file_list 안에 이미 해당 폴더안의 *.gft 파일 목록이 들어 있고,
              //file_count 안에 *.gft 글꼴수 가 들어 있으므로 이 정보를 사용하여
              //해당 [글꼴파일] 을 읽어 들이면 된다.
              //-----------------------------------------------------------------

              for(i = 0; i < file_count; i++)
              {
                //[기타 글꼴]--------------------------------------------------------------
                //*.gft 가 저장되는 시작 위치를 기록한다.
                fontresource->fonthandle[gft_load_count] = (unsigned int)gft_load_handle;

                //[글꼴이름 수집]
                //{
                    //[2010.01.26.화][중요추가!!!]
					STR_Assign(fontresource->names[gft_load_count].name, ((AnsiString)(file_list->Strings[i])).c_str());

                //}

                FILE_Open_forFontResource(font_path + file_list->Strings[i], gft_load_handle, &file_size);

                //[2022.09.11.일][중요수정]{************************************************************
				//파일 포인터를 다음 *.gft 저장 위치로 수정한다.
				//TC++2006 에서 이상 없는 코드.
				//((unsigned int)gft_load_handle) += file_size;
				//원래 위와 같은 것이나 C++Builder 10 에서는 LValue 오류가 발생하므로 아래와 같이 수정.
				gft_load_handle = (unsigned char *)((unsigned int)gft_load_handle + file_size);
				//}*************************************************************************************

				gft_load_count++;
				//-------------------------------------------------------------------------
              }

          //}

      //}

  //}

  return;

}

//[FONTPACK]--------------------------------------------------------------------

void __fastcall FONTPACK_GetHandle(struct FONTPACK **rFONTPACK)
{
  //[2006.09.27.수][생성!!!]{--------
  //[글꼴팩] 의 handle 을 넘겨 준다.
  //}--------------------------------

  (*rFONTPACK) = &_font;

  return;

}

void __fastcall FONTPACK_Init(void)
{
  //[2006.09.27.수][생성!!!]{-----
  //[글꼴팩] 을 전부 초기화 한다.

  //[2007.02.04.일][추가!!!]
  //[굵은글꼴] 정보를 추가한다.
  //}-----------------------------

  //[VAR]
  //{
      struct FONTPACK  *fontpack;
  //}

  //[핸들얻기]
  //{
      //해당 [글꼴팩] 의 handle 을 얻는다.
      FONTPACK_GetHandle(&fontpack);

  //}

  //[글꼴 초기화]
  //{
      fontpack->gft[d_FONTPACK_hangul_ix]       = NULL;
      fontpack->gft[d_FONTPACK_symbol_ix]       = NULL;
      fontpack->gft[d_FONTPACK_hanja_ix]        = NULL;
      fontpack->gft[d_FONTPACK_english_ix]      = NULL;

      fontpack->gft[d_FONTPACK_hangul_bold_ix]  = NULL;
      fontpack->gft[d_FONTPACK_symbol_bold_ix]  = NULL;
      fontpack->gft[d_FONTPACK_hanja_bold_ix]   = NULL;
      fontpack->gft[d_FONTPACK_english_bold_ix] = NULL;

  //}

  //[설정 초기화]
  //{
      //[글꼴] 의 [설정] 정보를 초기화 한다.
      fontpack->margin_size   = 0;
      fontpack->offset_left   = 0;
      fontpack->offset_right  = 0;
      fontpack->offset_top    = 0;
      fontpack->offset_bottom = 0;

      //[영문 전용]
      //{
          //[2010.01.25.월][중요추가!!!]
          fontpack->en_offset_left  = 0;
          fontpack->en_offset_right = 0;

      //}

  //}

  return;

}

void __fastcall FONTPACK_Register(struct FONTPACK  *pFONTpack,
                                  unsigned char    *pHANGUL,
                                  unsigned char    *pSYMBOL,
                                  unsigned char    *pHANJA,
                                  unsigned char    *pENGLISH,
                                  unsigned char    *pHANGULbold,
                                  unsigned char    *pSYMBOLbold,
                                  unsigned char    *pHANJAbold,
                                  unsigned char    *pENGLISHbold)
{
  //[2006.09.29.금][생성!!!]{---------------------------------------------------
  //[글꼴 리소스] 의 글꼴을 대상으로 현재 [글꼴묶음] 에 사용할 글꼴을 등록한다.
  //각 언어 별로 지정하되, 필요 없는 경우는 NULL 로 지정한다.

  //[2007.02.04.일][추가!!!]
  //[굵은글꼴] 정보도 같이 처리한다.
  //}---------------------------------------------------------------------------

  //[등록]
  //{
      pFONTpack->gft[d_FONTPACK_hangul_ix]  = pHANGUL;
      pFONTpack->gft[d_FONTPACK_symbol_ix]  = pSYMBOL;
      pFONTpack->gft[d_FONTPACK_hanja_ix]   = pHANJA;
      pFONTpack->gft[d_FONTPACK_english_ix] = pENGLISH;

      pFONTpack->gft[d_FONTPACK_hangul_bold_ix]  = pHANGULbold;
      pFONTpack->gft[d_FONTPACK_symbol_bold_ix]  = pSYMBOLbold;
      pFONTpack->gft[d_FONTPACK_hanja_bold_ix]   = pHANJAbold;
      pFONTpack->gft[d_FONTPACK_english_bold_ix] = pENGLISHbold;
  //}

  return;

}

void __fastcall FONTPACK_SetDefault(struct FONTPACK *pFONTpack)
{
  //[2006.10.15.일][생성!!!]{-------------------------
  //각각의 컨트롤에서 사용할 [기본 글꼴] 을 설정한다.
  //
  //[2018.07.02.월][중요수정!!!]----------------------
  //}-------------------------------------------------

  //[VAR]
  //{
      struct FONTRESOURCE  *fontresource;
  //}

  //[핸들얻기]
  //{
      FONTRESOURCE_GetHandle(&fontresource);
  //}

  //[기본 글꼴 설정]
  //{
      //[!]{--------------------------------------------------------------------------
      //system 글꼴은 "[한글]->[기호]->[한자]->[영어]" 순으로 [글꼴리소스] 에
      //배치되 있으므로 순서대로 해당 *.gft 글꼴의 handle 을 그대로 할당해 주면 된다.
      //}-----------------------------------------------------------------------------

      FONTPACK_Register(pFONTpack,
                        (unsigned char *)fontresource->fonthandle[0],
                        (unsigned char *)fontresource->fonthandle[1],
                        (unsigned char *)fontresource->fonthandle[2],
                        (unsigned char *)fontresource->fonthandle[3],
                        (unsigned char *)fontresource->fonthandle[4],
                        (unsigned char *)fontresource->fonthandle[5],
                        (unsigned char *)fontresource->fonthandle[6],
                        (unsigned char *)fontresource->fonthandle[7]);

  //}

  //[설정 초기화]
  //{
      //[2018.07.02.월][추가!!!]{-----------------------------------------------------------
      //<API_Str.cpp> 의 <_API_Str_DefaultFont_Get_StringOutAreaInfo()> 함수를 만드는중
      //부가 정보 초기화가 안돼있어 API 오류가 발생하는 것을 발견하고 추가.
      //
      //[글꼴] 을 사용하는 모든 [그림부품] 에서는 내부적으로 <FONTPACK_SetDefault()> 를
      //사용한뒤 아래 내용은 해당 [그림부품] 에 맞게 초기화 하여 사용하므로 문제가 없었으나
      //기본값으로 초기화는 반드시 필요하므로 금일 추가해 놓는다.
      //}-----------------------------------------------------------------------------------

      //[글꼴] 의 [설정] 정보 초기화.
      pFONTpack->margin_size   = 0;
      pFONTpack->offset_left   = 0;
      pFONTpack->offset_right  = 0;
      pFONTpack->offset_top    = 0;
      pFONTpack->offset_bottom = 0;

      //[영문 전용]
      //{
          pFONTpack->en_offset_left  = 0;
          pFONTpack->en_offset_right = 0;

      //}

  //}

}

bool __fastcall FONTPACK_SetFont_withName(//설정 대상이 되는 [글꼴묶음].
                                          struct FONTPACK  *pFontPack,
                                          //[글꼴묶음] 상의 등록 위치.
                                          int               pSetIndex,
                                          //[글꼴묶음] 에 할당할 [글꼴이름].
                                          char             *pFontName)
{
  //[2010.01.26.화][생성!!!]{--------------------------------------------------
  //[글꼴이름] 에 해당하는 [글꼴] 을 [글꼴자원] 에서 찾아서 지정 [글꼴묶음] 의
  //해당 [글꼴] 에 등록해 준다.
  //단, [글꼴] 자체의 [선행정보] 를 읽어서 [한글/기호/한자/영문] 인지 구분하고
  //[보통글꼴/굵은글꼴] 인지 구분하여 해당 위치에 등록해 주어야 한다.
  //크기는 상관없다(같은 크기끼리 묶는 것은 사용자의 몪이다).
  //이 경우는 [글꼴묶음] 자체를 별도 관리하면 된다.
  //이 경우에도 지금 이 함수는 해당 [글꼴] 을 등록하는데 필요하다.
  //}--------------------------------------------------------------------------

  //[VAR]
  //{
      //글꼴자원.
      struct FONTRESOURCE  *fontresource;

      //설정할 글꼴.
      unsigned char        *setFont;

      int    i;

  //}

  //[글꼴 자원 위치얻기]
  //{
      FONTRESOURCE_GetHandle(&fontresource);

  //}

  //[글꼴이름 목록에서 해당 글꼴 index 찾기]
  //{
      //[!]{-----------------------------------------------------
      //이미 정리된 [글꼴이름] 에서 해당 글꼴의 index 를 찾는다.
      //찾는 것이 없다면 <false> 를 반환한다.
      //}--------------------------------------------------------

      for(i = 0; i < fontresource->fontcount; i++)
      {
        if(STR_Match_NoCase(fontresource->names[i].name, pFontName) == true)
        {
          //일치하는 것을 찾았다.
          setFont = (unsigned char *)fontresource->fonthandle[i];

          //해당 하는 것을 찾았으므로 다음으로 계속 진행한다.
          goto lbFontFinded;

        }

      }

      //여기까지 온것은 일치하는 것이 없다.
      return(false);

      lbFontFinded:

  //}

  //[등록]
  //{
      //현재 글꼴을 구해진 해당 위치에 등록한다.
      pFontPack->gft[pSetIndex]  = setFont;

  //}

  return(true);

}

void __fastcall FONTPACK_Get_MaxHeight(//정보를 얻을 [글꼴묶음].
                                       struct FONTPACK  *pFontPack,
                                       //글꼴의 추가 여백설정까지 반영하는 경우는 true(기본 : false).
                                       bool              pFontOfs,
                                       //높이정보 반환.
                                       int              *rMaxHeight)
{
  //[2010.02.12.금][생성!!!]{-----------------------------------------------------------
  //[글꼴묶음] 에 등록된 모든 [글꼴] 을 검사하여 가장 큰 [문자높이] 를 구하여 반환한다.
  //}-----------------------------------------------------------------------------------

  //[VAR]
  //{
      //*.gft 파일의 header handle 을 얻는다.
      unsigned int  *header;

      int            maxHeight = 0, height = 0;

      int            i;

  //}

  for(i = 0; i < d_FontPack_GftMax; i++)
  {
    //[글꼴정보얻기]
    //{
        //[!]{-----------------------------------------------------------------------------------
        //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.
        //}--------------------------------------------------------------------------------------

        if(pFontPack->gft[i] != NULL)
        {
          //[선행정보] 위치 얻기(글꼴의 처음 시작 위치와 같다.)
          header = (unsigned int *)(pFontPack->gft[i]);

          //세로 크기만 구한다.
          height =  ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);

        }

    //}

    //[추가 여백 반영]
    //{
        if(pFontOfs == true)
        {
          //출력시 추가되는 여백을 반영하여 높이를 설정한다.
          height += (pFontPack->offset_top + pFontPack->offset_bottom);

        }

    //}

    //[최대크기 구하기]
    //{
        //현재 구한 것이 이전것 보다 크다면 현재값을 최대값으로 설정한다.
        //그렇지 않은 경우는 이전 최대값을 그대로 남겨둔다.
        if(maxHeight < height) { maxHeight = height; }

    //}

  }

  //[최대높이반환]
  //{
      (*rMaxHeight) = maxHeight;

  //}

}

//[글꼴 출력 함수]--------------------------------------------------------------

void __fastcall FONT_Get_MoonjaPtr_byORDER(//*.gft 파일 핸들.
                                           unsigned char  *pFONThandle,
                                           //문자순번.
                                           int             pORDER,
                                           //{font-data} 상의 byte 위치.
                                           int            *rPTRbyte,
                                           //{font-data} 상의 bit 위치.
                                           int            *rPTRbit)
{
  //[2006.09.30.토][생성!!!]{-----------------------------------------------
  //현재 [글꼴파일] 에서 pORDER 순번 문자의 {font-data} 상의 byte 위치와
  //bit 위치를 계산하여 반환한다.
  //이는 width, height 와 관련이 있으므로 부가 정보를 먼저 얻어서 처리한다.
  //}-----------------------------------------------------------------------

  //[주의!!]
  //{
      //이 함수는 [문자열 글꼴] 에서는 적용되지 않는다.
  //}

  //[VAR]
  //{
      //*.gft 파일의 header handle 을 얻는다.
      unsigned int  *header;

      int            width, height;

      //현재 문자 이전까지의 총 bit 수.
      int            total_bit = 0;

  //}

  //[글꼴정보]
  //{
      //---------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header = (unsigned int *)pFONThandle;

      //가로, 세로 크기를 구한다.
      width  =  ENDIAN_BigToLittle_4(header[d_HEADER_width_ix]);
      height =  ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);
      //---------------------------------------------------------------------------------------
  //}

  //[총비트수 구하기]
  //{
      //-----------------------------------------------------
      //현재 order 문자 이전 문자 까지의 충비트 수를 구한다.
      //현재 pORDER 은 이전 문자의 순번 크기가 된다.
      total_bit = (width * height) * pORDER;
      //-----------------------------------------------------
  //}

  //[index 구하기]
  //{
      //------------------------------------------------
      if(pORDER == 0)
      {
        //처음 위치를 갖는다.
        (*rPTRbyte) = 0;
        (*rPTRbit)  = 7;

      }
      else
      {
        //[총비트수] / 8 의 몫이 index-byte 가 된다.
        (*rPTRbyte) = total_bit / 8;

        //[총비트수] / 8 의 나머지가 index-bit 가 된다.
        (*rPTRbit)  = 7 - (total_bit % 8);

      }
      //------------------------------------------------
  //}

  return;

}

bool __fastcall FONT_Get_FontHandle_byCODE(//[사용 글꼴 묶음].
                                           struct FONTPACK   *pFONTPACK,
                                           //문자 code.
                                           unsigned short     pCODE,
                                           //해당 code 를 가진 [글꼴] 의 pFONTPACK 상의 index 를 반환한다.
                                           int               *rFONTindex)
{
  //[2006.09.30.토][생성!!!]{-------------------------------------------------------------
  //[글꼴 묶음] 에서 지정된 code 가 있는 [글꼴] 을 찾아서 해당 handle 을 반환한다.

  //[2007.02.04.일][수정!!!]
  //이전에는 글꼴의 handle 을 반환했으나 이 경우 사용의 융통성이 떨어진다.
  //즉, [일반글꼴] 과 [굵은글꼴] 은 index 상으로 4 의 크기 차이가 있다.
  //[일반글꼴 index] + 4  => [굵은글꼴 index] 가 되므로 간단하게 지정글꼴의 [굵은글꼴] 에
  //접근할수 있게 된다. 따라서, handle 을 직접 반환하지 않고 해당 글꼴의 index 를
  //반환하여 [굵은글꼴] 에 보다 쉽게 접근할수 있도록 하는 것이다.
  //해당하는 것이 없는 경우는 -1 을 반환한다.
  //}-------------------------------------------------------------------------------------

  //[설명]
  //{
      //[기본 글꼴] 의 경우는 간단하지만, [문자열 글꼴] 의 경우는 [문자 헤더 테이블] 을
      //전부 검사하여 해당 code 가 있는지 찾아 보아야 한다.
  //}

  //[code 범위]
  //{
      //-----------------------------
      //ks-hangul : 0xb0a1 - 0xc8fe.
      //ks-symbol : 0xa1a1 - 0xacfe.
      //ks-hanja  : 0xcaa1 - 0xfdfe.
      //english   :   0x00 -   0xff.
      //-----------------------------
  //}

  //[VAR]
  //{
      //*.gft 파일의 header handle 을 얻는다.
      unsigned int        *header;

      //[글꼴] 의 부가 정보를 얻는다.
      unsigned int         option;
      int                  count;
      unsigned int         coderange;
      unsigned short       code_start, code_end;
      unsigned short       code;

      //[문자열 글꼴] 의 경우 [문자 헤더 테이블] handle 을 가진다.
      unsigned long long  *moonja_header;

      int                  i, j;
  //}

  //-------------------------------------------------
  //[기본 글꼴], [문자열 글꼴] 을 구분하여 처리한다.
  //[글꼴 묶음] 에는 현재 4 개의 글꼴이 있다.
  //-------------------------------------------------

  for(i = 0; i < 4; i++)
  {                                           
    //--------------------------------------
    //[글꼴]이 등록된 경우만 처리해야 한다.
    if(pFONTPACK->gft[i] == NULL) continue;
    //--------------------------------------

    //[글꼴정보]
    //{
        //---------------------------------------------------------------------------------------
        //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

        //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
        header     = (unsigned int *)(pFONTPACK->gft[i]);

        option     = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);
        count      = ENDIAN_BigToLittle_4(header[d_HEADER_count_ix]);

        //code 범위를 구한다.
        coderange  = ENDIAN_BigToLittle_4(header[d_HEADER_coderange_ix]);
        code_start = (coderange >> 16) & 0x0000ffff;
        code_end   = (coderange >>  0) & 0x0000ffff;
        //---------------------------------------------------------------------------------------
    //}

    switch((option >> d_LANGUAGE_default_string_bt) & 0x00000001)
    {
      case d_default_bv : //[기본 글꼴]
      {
        //-------------------------------------------------------------------------
        //[기본 글꼴] 인 경우는 해당 [언어] code 범위 안에 있는지만 검사하면 된다.
        if((code_start <= pCODE) && (pCODE <= code_end))
        {
          //해당하는 [글꼴] 을 찾은 것이다.
          (*rFONTindex) = i;

          return(true);

        }
        //-------------------------------------------------------------------------
      } break;

      case d_string_bv  : //[문자열 글꼴]
      {
        //----------------------------------------------------------------------
        //[문자열 글꼴] 인 경우는 각각의 [문자 헤더] 를 전부 검색하여 처리한다.

        //[문자열 글꼴] 의 [문자헤더 테이블] 위치를 얻는다.
        moonja_header = (unsigned long long *)(&(header[d_HEADER_table_ix]));

        for(j = 0; j < count; j++)
        {
          //code 값 2byte 는 [문자헤더] 의 하위 2byte 가 된다.
          code = ENDIAN_BigToLittle_8(moonja_header[j]) & 0xffff;

          if(code == pCODE)
          {
            //해당하는 [글꼴] 을 찾은 것이다.
            (*rFONTindex) = i;

            return(true);

          }
        }
        //----------------------------------------------------------------------
      } break;

    }

  }

  //찾는 것이 없으므로 초기화 한다.
  (*rFONTindex) = -1;

  //여기까지 온것은 처리 불가.
  return(false);

}

void __fastcall FONT_Get_MoonjaOrder_byCODE(unsigned char   *pFONThandle,
                                            unsigned short   pCODE,
                                            int             *rORDER)
{
  //[2006.10.02.월][생성!!!]{---------------------------------------------
  //[기본 글꼴] 을 대상으로 code 에 해당하는 [순번] 을 계산하여 반환한다.
  //[언어] 에 따라서 code 범위가 다르므로 [언어] 따라 처리한다.
  //[문자열 글꼴] 의 경우는 [문자헤더] 에 모든 정보 가 들어 있으므로
  //여기서는 대상으로 하지 않는다.
  //}---------------------------------------------------------------------

  //[VAR]
  //{
      //*.gft 파일의 header handle 을 얻는다.
      unsigned int        *header;

      //[글꼴] 의 부가 정보를 얻는다.
      unsigned int         option;

      //[언어] 의 가장 첫 code 의 [상위/하위] byte  를 기록한다.
      unsigned short       fontcode_H, fontcode_L;

      //pCODE 의 [상위/하위] byte 를 기록한다.
      unsigned short       code_H, code_L;
  //}

  //[글꼴정보]
  //{
      //---------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header = (unsigned int *)pFONThandle;

      option = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);
      //---------------------------------------------------------------------------------------
  //}

  //[코드 분해]
  //{
      code_H = (pCODE >> 8) & 0x00ff;
      code_L = (pCODE >> 0) & 0x00ff;
  //}

  //[언어 분류]
  //{
      //[언어] 에 따라서 [시작 code] 값이 달라진다.
      //option 의 하위 30bit 로 [언어] 종류를 알수 있다.

      //[code 범위]{-----------------
      //ks-hangul : 0xb0a1 - 0xc8fe.
      //ks-symbol : 0xa1a1 - 0xacfe.
      //ks-hanja  : 0xcaa1 - 0xfdfe.
      //english   :   0x00 -   0xff.
      //}----------------------------

      switch(option & 0x3fffffff)
      {
        case d_LANGUAGE_KS_hangul_bt : //[KS:한글]
        {
          //시작 코드 : 0xb0a1.
          fontcode_H = 0xb0;
          fontcode_L = 0xa1;

        } break;

        case d_LANGUAGE_english_bt   : //[영어]
        {
          //시작 코드 : 0x0000.
          fontcode_H = 0x00;
          fontcode_L = 0x00;

        } break;

        case d_LANGUAGE_KS_symbol_bt : //[KS:기호]
        {
          //시작 코드 : 0xa1a1.
          fontcode_H = 0xa1;
          fontcode_L = 0xa1;

        } break;

        case d_LANGUAGE_KS_hanja_bt  : //[KS:한자]
        {
          //시작 코드 : 0xcaa1.
          fontcode_H = 0xca;
          fontcode_L = 0xa1;

        } break;

      }
      
  //}
        
  //[순번 계산]
  //{
      //----------------------------------------------------------------------------
      //[영문] 의 경우는 (code_H - fontcode_H) 값이 항상 0 이 되므로 0*94 가 되므로
      //아무 상관없이 처리될수 있다.
      (*rORDER) = (code_H - fontcode_H)*94 + (code_L - fontcode_L);
      //----------------------------------------------------------------------------
  //}

  return;

}

bool __fastcall FONT_Get_MoonjaPtr_byCODE(//[사용 글꼴 묶음].
                                          struct FONTPACK   *pFONTPACK,
                                          //문자순번.
                                          unsigned short     pCODE,
                                          //해당 code 를 가진 [글꼴] 의 pFONTPACK 상의 index 를 반환한다.
                                          int               *rFONTindex,
                                          //문자순번.
                                          int               *rMOONJAorder,
                                          //{font-data} 상의 byte 위치.
                                          int               *rPTRbyte,
                                          //{font-data} 상의 bit 위치.
                                          int               *rPTRbit)
{
  //[2006.09.30.토][생성!!!]{-------------------------------------------------------------
  //현재 [글꼴 파일] 에서 지정된 code 에 해당하는 문자의 {font-data} 상의
  //위치를 찾아서 반환한다.

  //[2007.02.05.월][수정!!!]
  //이전에는 글꼴의 handle 을 반환했으나 이 경우 사용의 융통성이 떨어진다.
  //즉, [일반글꼴] 과 [굵은글꼴] 은 index 상으로 4 의 크기 차이가 있다.
  //[일반글꼴 index] + 4  => [굵은글꼴 index] 가 되므로 간단하게 지정글꼴의 [굵은글꼴] 에
  //접근할수 있게 된다. 따라서, handle 을 직접 반환하지 않고 해당 글꼴의 index 를
  //반환하여 [굵은글꼴] 에 보다 쉽게 접근할수 있도록 하는 것이다.
  //해당하는 것이 없는 경우는 -1 을 반환한다.
  //}-------------------------------------------------------------------------------------

  //[설명!!!]
  //{
      //-------------------------------------------------------------------------------
      //먼저 [글꼴 묶음] 에서 pCODE 가 들어 있는 [글꼴] 을 찾고,
      //이 [글꼴] 을 대상으로 [문자] 의 위치를 찾아서 반환해야 한다.
      //
      //[기본   글꼴] : pCODE 에 해당하는 문자 [순번] 을 먼저 찾고, 이 순번을 사용하여
      //                [문자위치] 를 간단하게 찾을수 있다.
      //
      //[문자열 글꼴] : [문자헤더] 에서 pCODE 에 해당하는 [문자] 의 위치 정보까지
      //                전부 들어 있으므로 이 정보를 추출하여 반환하면 된다.
      //-------------------------------------------------------------------------------
  //}

  //[VAR]
  //{ 
      int                  font_index;

      unsigned char       *font;

      //*.gft 파일의 header handle 을 얻는다.
      unsigned int        *header;

      int                  width, height;

      //현재 문자 이전까지의 총 bit 수.
      int                  total_bit = 0;

      //[글꼴] 의 부가 정보를 얻는다.
      unsigned int         option;
      int                  count;
      unsigned short       code;

      //[문자열 글꼴] 의 경우 [문자 헤더 테이블] handle 을 가진다.
      unsigned long long  *moonja_header_handle;
      unsigned long long   moonja_header;

      int                  i;
      int                  order;
  //}

  //[글꼴 얻기]
  //{
      //--------------------------------------------------------------------
      //pCODE 에 해당하는 [글꼴] 을 [글꼴 묶음] 에서 찾는다.
      if(FONT_Get_FontHandle_byCODE(pFONTPACK, pCODE, &font_index) != true)
      {
        return(false);

      }

      font = pFONTPACK->gft[font_index];

      //현재 [글꼴] 을 반환한다.
      (*rFONTindex)  = font_index;
      //--------------------------------------------------------------------
  //}

  //[글꼴정보]
  //{
      //---------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header = (unsigned int *)font;

      //가로, 세로 크기를 구한다.
      width  = ENDIAN_BigToLittle_4(header[d_HEADER_width_ix]);
      height = ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);

      option = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);
      count  = ENDIAN_BigToLittle_4(header[d_HEADER_count_ix]);
      //---------------------------------------------------------------------------------------
  //}

  //[문자 위치 구하기]
  //{
      switch((option >> d_LANGUAGE_default_string_bt) & 0x00000001)
      {
        case d_default_bv : //[기본 글꼴]
        {
          //-----------------------------------------------------------------------
          //[기본 글꼴] 인 경우는 [문자 순번] 을 먼저 구한뒤 해당 함수를 호출한다.

          //현 code 에 해당하는 [문자 순번] 을 먼저 구한다.
          FONT_Get_MoonjaOrder_byCODE(font, pCODE, &order);

          //[문자 순번] 의 [문자 위치] 를 구한다.
          FONT_Get_MoonjaPtr_byORDER(font, order, rPTRbyte, rPTRbit);

          //pCODE 에 해당하는 문자의 [문자순번] 을 반환한다.
          (*rMOONJAorder) = order;

          return(true);
          //-----------------------------------------------------------------------

        } break;

        case d_string_bv  : //[문자열 글꼴]
        {
          //---------------------------------------------------------------------------
          //[문자열 글꼴] 인 경우는 각각의 [문자 헤더] 에 이미 모든 정보가 있으므로
          //pCODE 를 가지는 [문자 헤더] 를 추출하여 [문자 위치] 를 추출한다.

          //[문자열 글꼴] 의 [문자 헤더 테이블] 위치를 얻는다.
          moonja_header_handle = (unsigned long long *)(&(header[d_HEADER_table_ix]));

          for(i = 0; i < count; i++)
          {
            //[문자 헤더] 를 구한다.
            moonja_header = ENDIAN_BigToLittle_8(moonja_header_handle[i]);

            //code 값 2byte 는 [문자 헤더] 의 하위 2byte 가 된다.
            code = moonja_header & 0xffff;

            if(code == pCODE)
            {
              //pCODE 의 [문자헤더] 를 찾았으므로 [문자 위치] 정보를 추출한다.

              //[문자 헤더 구조]{----------------------------------
              //{   DW   } + {byte 위치} + {bit 위치} + {  code  }
              // .[63:51]     .[50:19]      .[18:16]     .[15:0]
              //   13bit        32bit         3bit         16bit
              //  x : byte 크기.
              // .x : bit 번호.
              //}--------------------------------------------------

              //[문자 위치] 추출.
              (*rPTRbyte) = (moonja_header >> 19) & 0xffffffff;  //32bit 크기.
              (*rPTRbit)  = (moonja_header >> 16) & 0x07;        // 3bit 크기.

              //pCODE 에 해당하는 문자의 [문자순번] 을 반환한다.
              (*rMOONJAorder) = i;

              return(true);

            }

          }
          //---------------------------------------------------------------------------

        } break;
        
      }
  //}

  //여기까지 온것은 처리 불가.
  return(false);

}

bool __fastcall FONT_Out_Moonja(//[문자] 를 출력할 bitmap handle.
                                Graphics::TBitmap  *pVIEWhandle,
                                //[사용 글꼴 묶음].
                                struct FONTPACK    *pFONTPACK,
                                //문자를 표시할 좌표.(BASE:0)
                                int                 pX,
                                int                 pY,
                                //문자색.
                                int                 pMOONJAcolor,
                                //배경색.
                                int                 pBACKcolor,
                                //배경색투명속성지정.
                                bool                pBACKtransparent,
                                //출력 문자 코드.
                                unsigned short      pCODE,
                                //출력된 문자 width, height 정보 반환.
                                //[2012.05.15.화][수정!!!]
                                //NULL 이 아닌 경우만 반환.
                                int                *rWIDTH,
                                int                *rHEIGHT)
{
  //[2006.10.02.월][생성!!!]{--------------------------------------------------
  //pCODE 에 해당하는 [문자] 를 [글꼴 묶음] 에서 찾아서 출력한다.
  //[기본 글꼴] 이건 [문자열 글꼴] 이건 간에 [문자 위치] 만 알면
  //{font-data} 에서 간단하게 문자를 추출할수 있으므로 구분없이 사용할수 있다.
  //
  //[2012.05.15.화][수정!!!]---------------------------------------------------
  //}--------------------------------------------------------------------------

  //[주의!!!]
  //{
      //-------------------------------------------------------------------------
      //[문자] [좌/우 공백] 의 경우는 글꼴을 사용하는 프로그램에서 [옵션] 으로
      //지정되는 것으로 이 함수를 사용하는 곳에서 이 [옵션] 을 적용하여 pX, pY
      //값을 지정해 주는 것으로 처리해야 한다.
      //
      //[고정/가변폭] 을 구분하여 처리하되, 둘다 일단 DW 값을 구하여 이 DW 를
      //width 로 하여 이 폭 만큼만 처리해야 한다.
      //[공백] 문자의 경우에는 bit 값이 없으므로 DW 범위값이 매우 중요해진다.
      //
      //즉, [기본/문자열 글꼴], [고정/가변 글꼴] 을 구분하는 것은 DW 값을 구하기
      //위한 것이고 실제 출력시에는 전혀 구분이 없다.
      //-------------------------------------------------------------------------
  //}

  //[중요!!!]
  //{
      //-------------------------------------------------------------------------------
      //내부적으로 전역변수로 되있는 [문자 설정]을 참고하여 [문자] 를 출력해 주고,
      //[문자 설정] 이 적용된 출력된 문자(box)의 width, height 값을 계산하여 반환한다.
      //-------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 를 출력하지 않고 행을 바꿀 정보만 반환한다.
      //-------------------------------------------------------------------------------
  //}

  //[2007.01.19.금][추가!!!]
  //{
      //pVIEWhandle 영역을 벗어나는 경우는 처리하지 않는다.
      //단, 걸치는 문자는 전부 출력한다.
      //이는 수평으로 긴 문자열의 경우 모두 출력하게 되면 출력되는 문자수가 많아져서
      //출력 속도가 느려지기 때문이다.
  //}

  //[VAR]
  //{
      //표시할 영역 handle.
      Graphics::TBitmap    *bmp = pVIEWhandle;

      //사용할 [글꼴].
      unsigned char        *font;
      int                   font_index;

      //*.gft 파일의 header handle 을 얻는다.
      unsigned int         *header;

      //출력할 [문자] 의 [순번].
      int                   moonja_order;

      //출력할 [문자] 의 {font-data} 상위 위치.
      int                   index_byte, index_bit;

      //글꼴 정보.
      int                   width, height;
      unsigned int          option;
      int                   DW;
      int                   color;

      //[기본:가변 글꼴] 의 경우 DW-table 에 접근하기 위한 handle.
      //DW-table 은 각각 2byte 로 구성되 있다.
      unsigned short       *DW_table;

      //{font-data} 의 handle.
      unsigned char        *fontdata;

      //[문자열 글꼴] 의 경우 [문자 헤더 테이블] handle 을 가진다.
      unsigned long long   *moonja_header_handle;
      unsigned long long    moonja_header;

      //[view]
      //{
          //-------------------------------
          RGBTRIPLE        *line_ptr;

          int               x, y;
          int               bit_val   = 0;
          //-------------------------------
      //}

      //실제 margin 이 적용된 문자 출력 영역.
      int                   box_width, box_height;

      //순수 [문자] 출력 좌표.
      int                   mX, mY;

      int                   i;

      bool                  is_CRLF = false;
  //}

  //[문자 출력 위치 X offset 적용]
  //{
      //-----------------------------------
      //출력 좌표 X 의 offset 을 적용한다.
      pX += pFONTPACK->margin_size;
      //-----------------------------------
  //}

  //[CRLF 처리]
  //{
      //-----------------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 가 없는 것이므로 일단 [공백] 으로 대체한다.
      //단지 정보를 얻기 위한 것으로 이 함수 중간의 해당 처리부에서 정보를 얻기 위하여 필요하다.
      //이 [문자] 는 실제 출력되지는 않으며, 각각의 해당 처리 함수에서 해당 하지 않는 code 로
      //인하여 return(fasle)  로 처리되는 것을 막기 위한 것이다.
      if(pCODE == 0x0d0a)
      {
        pCODE   = ' ';
        is_CRLF = true;

      }
      //-----------------------------------------------------------------------------------------
  //}                              

  //[문자 위치 얻기]
  //{
      //---------------------------------------------------------------------------------------------------------------------
      //출력할 문자의 {font-data} 상의 위치를 얻는다.
      //동시에 [문자헤더] 에 접근할 경우를 위하여 [문자순번] 도 같이 얻는다.
      //이 정보는 [가변폭 글꼴] 인 경우 [문자헤더] 안의 DW 값을 얻는데 필요하다. 

      //[중요수정!!!][2007.01.15.월]
      //{
          //'똠' 등의 문자가 입력되는 경우, KS5601 완성형에서 지원하지 않으므로 자동으로 [조합형코드] 로 OS 가 바뀌어 주는데
          //이 [조합형코드] 는 지원하고 있지 않으므로 FONT_Get_MoonjaPtr_byCODE() 함수에서 false 가 된다.
          //이 경우 문자가 출력되지 못하고 종료되므로 이를 막기 위하여 해당하지 않는 코드의 경우는 무조건
          //[KS-기호] 중의 스폰지모양의 사각형을 출력하는 문자코드 0xa2c6 으로 코드르 바꾸어 주어 다시
          //FONT_Get_MoonjaPtr_byCODE() 함수를 호출하여 이 문자를 출력하는 것으로 한다.
          //이런 문제는 반드시 [한글] 등의 2 byte 문자에서 발생하므로 같은 2 byte 문자코드인 0xa2c6 으로
          //바꾸는 것이 보기도 좋고 확실하다. ? 등으로 바꾸는 경우는 혼동을 일으킬수 있다.
      //}

      ETC_MOONJA:

      if(FONT_Get_MoonjaPtr_byCODE(pFONTPACK, pCODE, &font_index, &moonja_order, &index_byte, &index_bit) != true)
      {
        //없는 코드 문자로 대체한다.
        pCODE = 0xa2c6;

        //바뀐 코드로 다시 처리한다.
        goto ETC_MOONJA;

      }

      //[글꼴] 관리주소를 얻는다.
      font = pFONTPACK->gft[font_index];
      //---------------------------------------------------------------------------------------------------------------------
  //}

  //[글꼴정보]
  //{
      //------------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header   = (unsigned int *)font;

      //가로, 세로 크기를 구한다.
      width    = ENDIAN_BigToLittle_4(header[d_HEADER_width_ix]);
      height   = ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);
      option   = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);

      //{font-data} 가 시작되는 handle 을 얻는다.
      fontdata = (unsigned char *)(&(font[ENDIAN_BigToLittle_4(header[d_HEADER_dataindex_ix])]));
      //------------------------------------------------------------------------------------------
  //}

  //[DW 값 구하기]
  //{
      //[설명]{----------------------------------------------------------------
      //출력폭을 결정하는 DW 값을 얻는다.
      //[기본 글꼴]
      //=>[고정폭] : [글꼴 헤더] 의 DW 값을 바로 사용하면 된다.
      //=>[가변폭] : [DW-table] 의 해당 문자 order 의 DW 값을 사용한다.
      //
      //[문자열 글꼴]
      //[문자열 글꼴] 은 [고정/가변폭] 에 상관없이 각각의 [문자헤더] 안에 모든
      //정보가 있므으로 각각의 [문자헤더] 안의 DW 값을 사용한다.
      //}----------------------------------------------------------------------

      switch((option >> d_LANGUAGE_default_string_bt) & 0x00000001)
      {
        case d_default_bv : //[기본 글꼴]
        {
          //[고정/가변 글꼴] 에 따라서 DW 정보 위치가 달라지므로 구분하여 처리한다.
          switch((option >> d_LANGUAGE_fixed_variable_bt) & 0x00000001)
          {
            case d_fixed_bv    : //[고정폭 글꼴]
            {
              //[고정폭] 인 경우는 [글꼴 헤더] 안의 DW 기본 값을 사용하면된다.
              DW = ENDIAN_BigToLittle_4(header[d_HEADER_DWinfo_ix]);

            } break;

            case d_variable_bv : //[가변폭 글꼴]
            {
              //[가변폭] 인 경우는 DW-table(2byte 단위) 에서 지금 문자의 DW 값을 추출한다.
              //Big-Endian 으로 되 있으므로 변환처리한다.

              //DW-table 의 handle 을 얻는다.
              DW_table = (unsigned short *)(&(((unsigned int *)font)[d_HEADER_table_ix]));

              //현 문자의 DW 값을 얻는다.
              DW = ENDIAN_BigToLittle_2(DW_table[moonja_order]);

            } break;

          }

        } break;

        case d_string_bv  : //[문자열 글꼴]
        {
          //[문자 헤더 구조][64bit]{---------------------------
          //{   DW   } + {byte 위치} + {bit 위치} + {  code  }
          // .[63:51]     .[50:19]      .[18:16]     .[15:0]
          //   13bit        32bit         3bit         16bit
          //  x : byte 크기.
          // .x : bit 번호.
          //}--------------------------------------------------

          //해당 문자의 [문자 헤더] 의 DW 값을 추출한다.

          //[문자열 글꼴] 의 [문자 헤더 테이블] 위치를 얻는다.
          moonja_header_handle = (unsigned long long *)(&(header[d_HEADER_table_ix]));

          //문자의 [문자 헤더] 정보를 구한다.
          moonja_header = ENDIAN_BigToLittle_8(moonja_header_handle[moonja_order]);

          //DW 값을 구한다. ([문자열 글꼴] 에서는 13bit 크기를 갖는다.)
          DW = (moonja_header >> 51) & 0x1fff;

        } break;

      }
  //}

  //[출력 영역 정보]
  //{
      //[!]{------------------------------------------
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      //}---------------------------------------------

      //[문자 출력 폭 계산]
      //{
          //[2010.01.25.월][중요수정!!!]{-----------------------------------------------
          //[영문] 의 경우는 미리 지정한 전용 [왼쪽/오른쪽 여백] 을 추가해 주어야 한다.
          //[영문글꼴] [글꼴묶음] 의 index[3, 7] 에 해당한다.
          //}---------------------------------------------------------------------------

          if((font_index == 3) || (font_index == 7))
          {
            //[영문글꼴] 인 경우.

            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right +
                         pFONTPACK->en_offset_left + pFONTPACK->en_offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

            //순수 [문자] 출력 좌표 구하기.
            mX = pX + pFONTPACK->offset_left + pFONTPACK->en_offset_left;
            mY = pY + pFONTPACK->offset_top;

          }
          else
          {
            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

            //순수 [문자] 출력 좌표 구하기.
            mX = pX + pFONTPACK->offset_left;
            mY = pY + pFONTPACK->offset_top;

          }

      //}

  //}

  //[출력 없이 문자 폭/높이 정보만 얻기인가?]
  //{
      //[2012.05.15.화][추가!!!]{--------------------------------------
      //<pVIEWhandle:NULL> 인 경우로 출력할 대상이 없는 경우는
      //출력 없이 [문자:폭/높이] 정보만 얻는 경우로 본다.
      //
      //문자가 [한글/영문] 인 경우 서로 폭이 다르기 때문에 다른 곳에서
      //이 각각의 [문자:폭/높이] 정보를 얻기 위한 것이다.
      //}--------------------------------------------------------------

      if(pVIEWhandle == NULL)
      {
        //각 정보만 반환하고 바로 종료.
        if(rWIDTH  != NULL) { (*rWIDTH)  = box_width;  }
        if(rHEIGHT != NULL) { (*rHEIGHT) = box_height; }

        return(true);

      }

  //}

  //[CRLF 처리]
  //{
      //-------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 를 출력하지 않고 행을 바꿀 정보만 반환한다.
      if(is_CRLF == true)
      {
        //-----------------------------------------------
        //[문자] 출력 영역 정보 반환.
        //[2012.05.15.화][수정!!!]-----------------------
        //NULL 이 아닌 경우만 반환.
        if(rWIDTH  != NULL) { (*rWIDTH)  = box_width;  }
        if(rHEIGHT != NULL) { (*rHEIGHT) = box_height; }
        //-----------------------------------------------

        return(true);

      }
      //-------------------------------------------------------------------------------
  //}

  //[출력유효영역검사][2007.01.19.금][추가!!!]
  //{
      //실제 영역안에만 문자가 출력 되도록 영역을 검사한다.
      if(!(((0 - box_width)  <= pX) && (pX <= (bmp->Width  + box_width)) &&
           ((0 - box_height) <= pY) && (pY <= (bmp->Height + box_height))))
      {
        //[!]{------------------------------------------
        //[문자] 출력 영역 정보는 반드시 반환해야 한다.
        //[2012.05.15.화][수정!!!]----------------------
        //NULL 이 아닌 경우만 반환.
        //}---------------------------------------------

        if(rWIDTH  != NULL) { (*rWIDTH)  = box_width;  }
        if(rHEIGHT != NULL) { (*rHEIGHT) = box_height; }

        //출력 영역을 벗어나는 경우는 처리하지 않는다.
        return(true);

      }
      
  //}

  //[문자 출력]
  //{
      //----------------------------------------------------------------------
      //DW 정보를 바탕으로 문자를 지정 영역에 표시한다.
      //[문자] 를 출력할때 margin 영역의 경우도 같이 처리한다.
      //즉, 전체 box 에서 [문자] 영역은 {font-data} 를 처리하고 margin 영역은
      //[문자 배경색] 으로 칠해주면 된다.
      //----------------------------------------------------------------------

      //[왼쪽->오른쪽] && [위->아래] 로 재생해준다.
      for(y = pY; y < (pY + box_height); y++)
      {
        if((0 <= y) && (y < bmp->Height))
        {
          //[line_ptr]{-----------------------------
          //[행] 의 pointer 를 얻는다.
          line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
          //}---------------------------------------
        }
        else
        {
          line_ptr = NULL;

          //[주의!!!]{--------------------------------------------------------------------
          //[문자 한개] 의 경우도 [출력 경계선] 에 걸릴수 있으므로 여기서 바로 break 하면
          //표시 영역에 있는 문자의 "나머지 부분" 이 출력되지 않는다.
          //그러므로, 여기서 break 를 사용하여 종료하지 않아야 한다.
          //}-----------------------------------------------------------------------------
        }

        for(x = pX; x < (pX + box_width); x++)
        {
          //----------------------------------------------------------------------
          //[문자] 영역인지 [margin] 영역인지 구분하여 처리한다.
          //일단, [문자] 영역에 해당하지 않는 경우는 전부 [margin] 영역으로 본다.
          //DW 폭에 한하여 표시해야 한다.
          //----------------------------------------------------------------------

          if(((mX <= x) && (x < (mX + DW))) &&
             ((mY <= y) && (y < (mY + height))))
          {
            //[font-data 출력 영역]

            //[font-data]{----------------------------------------
            bit_val = (fontdata[index_byte] >> index_bit) & 0x01;
            //}---------------------------------------------------

            //문자색.
            if(bit_val == 1) { color = pMOONJAcolor; }
            //바탕색.
            else             { color = pBACKcolor;   }

            if((0 <= x) && (x < bmp->Width))
            {
              if((line_ptr != NULL) && (!((bit_val == 0) && (pBACKtransparent == true))))
              {
                //[pixel color]{------------------------------
                line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                //}-------------------------------------------
              }

            }

            //[index 수정]
            //{
                //---------------------------
                if(index_bit == 0)
                {
                  //새로운 byte 를 시작한다.
                  index_byte++;
                  //bit 초기화.
                  index_bit = 7;

                }
                else
                {
                  index_bit--;

                }
                //---------------------------
            //}

            //현 행의 [문자] 의 마지막 bit 를 처리한 상태라면...
            //반드시 이 위치에서 처리되어야 한다.
            if(x == (mX + DW - 1))
            {
              //[{font-data} 소진]{-----------------------------------------------
              //"0 - width" 까지 사용되지 않은 이 행의 남은 {font-data} 를 여기서
              //완전히 소진해 주어야 한다.
              //(width - DW) 크기가 아직 남아 있다.
              //}-----------------------------------------------------------------

              for(i = 0; i < (width - DW); i++)
              {
                //[index 수정]
                //{
                    //---------------------------
                    if(index_bit == 0)
                    {
                      //새로운 byte 를 시작한다.
                      index_byte++;
                      //bit 초기화.
                      index_bit = 7;

                    }
                    else
                    {
                      index_bit--;

                    }
                    //---------------------------
                //}
              }

            }

          }
          else
          {
            //이 경우는 margin 영역에 들어 있는 겻이므로 [문자 배경색] 으로 칠한다.
            color = pBACKcolor;

            if((0 <= x) && (x < bmp->Width))
            {
              if((line_ptr != NULL) && (!((bit_val == 0) && (pBACKtransparent == true))))
              {
                //[pixel color]{------------------------------
                line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                //}-------------------------------------------
              }

            }

          }

        }

      }
  //}

  //[반환]
  //{
      //----------------------------
      //[문자] 출력 영역 정보 반환.
      //[2012.05.15.화][수정!!!]----
      //NULL 이 아닌 경우만 반환.
      //}---------------------------

      if(rWIDTH  != NULL) { (*rWIDTH)  = box_width;  }
      if(rHEIGHT != NULL) { (*rHEIGHT) = box_height; }

  //}

  return(true);

}

bool __fastcall FONT_Out_String(//[문자] 를 출력할 bitmap handle.
                                Graphics::TBitmap  *pVIEWhandle,
                                //[사용 글꼴 묶음].
                                struct FONTPACK    *pFONTPACK,
                                //문자열을 출력할 시작 위치.(BASE:0)
                                //수정된 값을 반환하기도 한다.
                                int                 pX,
                                int                 pY,
                                //문자색.
                                int                 pMOONJAcolor,
                                //배경색.
                                int                 pBACKcolor,
                                //배경색투명속성지정.
                                bool                pBACKtransparent,
                                //출력할 문자열.
                                char               *pSTRING,
                                //문자열 출력후 변경된 (x, y) 좌표를 반환한다.
                                int                *rX,
                                int                *rY)
{
  //[2006.10.07.토][생성!!!]{-----------------------------------------------
  //문자열을 전달 받아서 지정 위치에 출력한다.
  //단, 반드시 "CR/LF" "0Dh/0Ah"도 완벽하게 지원해야 한다.(순서대로)
  //<tab> 은 지원하지 않으므로 만약 발견 된다면 공백으로 대치하여 처리한다.
  //실제 에디터 상에서는 아예 <tab> 을 지원하지 않는다.
  //사용하는 경우는 역시 공백으로 처리한다.
  //}-----------------------------------------------------------------------

  //[중요!!!]
  //{
      //-----------------------------------------------------------------------
      //[문자] [좌/우 공백] 의 경우는 글꼴을 사용하는 프로그램에서 [옵션] 으로
      //지정되는 것으로 이 함수를 사용하는 곳에서 이 [옵션] 을 적용하여 pX, pY
      //값을 지정해 주는 것으로 처리해야 한다.
      //이 [설정] 은 [글꼴 묶음] 안에 포함되 있다.
      //-----------------------------------------------------------------------
  //}

  //[2006.11.01.수][추가!!!]
  //{
      //---------------------------------------------------------------------------
      //문자가 출력 영역에 위치하는 지만 검사하는 경우는 문서량이 많은 경우
      //모든 문자를 다 처리하게 되므로 처리 시간이 많이 결린다.
      //이를 막기 위하여 [표시영역] 정보를 바탕으로 출력되는 행의 범위를 구하여
      //이 범위 한에 해당하는 문서행만 출력하고 나머지는 아예 처리하지 않도록한다.
      //이렇게 하면, 아무리 문서량이 많아도 표시 영역에 해당하는 행만 출력하므로
      //문서 량에 따라 처리 속도가 거의 차이가 없게 된다.
      //---------------------------------------------------------------------------
  //}

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             box_width, box_height;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //[출력행계산관련]
      //{
          //현재 출력하는 문서의 행번호.
          int         line_number = 0;

          //문자 출력 행의 높이.
          int         line_height;
          //출력 시작 행 번호(BASE:0)
          int         doc_line_start;
          //출력 끝 행 번호(BASE:0)
          int         doc_line_end;
      //}
  //}

  //[출력 행 정보 계산]
  //{
      //[행높이 구하기]{------------------------------------------------------------------------------------------------
      //[글꼴] 의 크기를 알기 위한 CRLF 문자 출력.
      FONT_Out_Moonja(pVIEWhandle, pFONTPACK, 0, 0, pMOONJAcolor, pBACKcolor, false, 0x0d0a, &box_width, &line_height);
      //----------------------------------------------------------------------------------------------------------------

      //[설명!!!]{------------------------------------------------------
      //출력 행의 범위를 계산한다.
      //여기서 "행" 은 "문서" 의 행을 말한다.(출력 영역의 행이 아니다.)
      //여기서 구한 두행 사이의 문서행만 실제로 출력하게 된다.
      //}---------------------------------------------------------------

      if(pY < 0)
      {
        //출력 시작 위치가 [음수] 인 경우, [음수 영역] 은 출력대상이 되지 않는다.

        //[출력 시작 행]
        doc_line_start = ((-1) * pY) / line_height;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
      else
      {
        //표시영역안은 항상 문서의 0 행부터 출력하면 된다.

        //[출력 시작 행]
        doc_line_start = 0;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      //[앞선 무효영역 제거]
      //{
          //doc_line_start 보다 작은 행은 표시할 필요가 없으므로 CRLF 를 찾아서
          //doc_line_start 행의 첫 문자의 위치를 찾아서 여기서 부터 출력한다.

          for(i = 0, line_number = 0;
              //[문자열] 끝이 나올때 까지 처리한다.
              pSTRING[i] != '\0';
             )
          {
            //처음행은 CRLF 전에 위치하므로 여기서 먼저 행을 검사한다.
            if(line_number == doc_line_start)
            {
              //출력으르 시작할 문서의 행을 얻었으므로 다음 처리로 들어간다.
              break;

            }

            if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
            {
              //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

              //다음 행의 좌표로 수정한다.
              pX  = 0;
              pY += line_height;

              i  += 2;

              //다음 행번호를 지정한다.
              line_number++;

            }
            else
            {
              i++;

            }

          }

      //}

      for(/*위에서 계속되는 값을 사용한다.*/;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pSTRING[i] != '\0';
         )
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_Moonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                             &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }
        else if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
        {
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Out_Moonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                             &box_width, &box_height) != true)
          {
            return(false);
          }

          //다음 행의 좌표로 수정한다.
          pX  = 0;
          pY += box_height;

          i  += 2;

          //다음 행번호를 지정한다.
          line_number++;

          if(!(line_number <= doc_line_end))
          {
            //처리행을 넘었으므로 더이상 처리하지 않는다.
            goto END;

          }

        }

        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //[!]{--------------------------
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.
          //}-----------------------------

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);



          //[문자] 출력.
          if(FONT_Out_Moonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                             &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Out_Moonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                             &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }

      }
  //}

  END:

  (*rX) = pX;
  (*rY) = pY;

  return(true);

}

bool __fastcall FONT_Out_Moonja2(//[문자] 를 출력할 bitmap handle.
                                 Graphics::TBitmap  *pVIEWhandle,
                                 //[사용 글꼴 묶음].
                                 struct FONTPACK    *pFONTPACK,
                                 //문자를 표시할 좌표.(BASE:0)
                                 int                 pX,
                                 int                 pY,
                                 //문자색.
                                 int                 pMOONJAcolor,
                                 //배경색.
                                 int                 pBACKcolor,
                                 //배경색투명속성지정.
                                 bool                pBACKtransparent,
                                 //출력 문자 코드.
                                 unsigned short      pCODE,
                                 //[field option]--------------------------------
                                 //밑줄 종류.
                                 int                 pUNDERLINEkind,
                                 //[공백] 에도 적용할지여부.
                                 bool                pUNDERLINEspace,
                                 //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                 int                 pUNDERLINEoffset,
                                 //밑줄 색.
                                 int                 pUNDERLINEcolor,
                                 //----------------------------------------------
                                 //출력된 문자 width, height 정보 반환.
                                 int                *rWIDTH,
                                 int                *rHEIGHT)
{
  //[2006.10.18.수][생성!!!]{----------------------------------------------------
  //FONT_Out_Moonja() 함수에 기능을 추가한 함수이다.
  //문자 영역 아래에 "밑줄" 추가 설정을 할수 있도록 한다.
  //이는 PALM-OS 의 Field 기능을 모방한 것이다.
  //"밑줄" 은 [점선/실선] 두 종류로 지정할수 있고, 표시 위치는 지정 값을 따른다.
  //}----------------------------------------------------------------------------

  //[2007.01.19.금][추가!!!]
  //{
      //pVIEWhandle 영역을 벗어나는 경우는 처리하지 않는다.
      //단, 걸치는 문자는 전부 출력한다.
      //이는 수평으로 긴 문자열의 경우 모두 출력하게 되면 출력되는 문자수가 많아져서
      //출력 속도가 느려지기 때문이다.
  //}

  //[VAR]
  //{
      //표시할 영역 handle.
      Graphics::TBitmap    *bmp = pVIEWhandle;

      //사용할 [글꼴].
      unsigned char        *font;
      int                   font_index;

      //*.gft 파일의 header handle 을 얻는다.
      unsigned int         *header;

      //출력할 [문자] 의 [순번].
      int                   moonja_order;

      //출력할 [문자] 의 {font-data} 상위 위치.
      int                   index_byte, index_bit;

      //글꼴 정보.
      int                   width, height;
      unsigned int          option;
      int                   DW;
      int                   color;

      //[기본:가변 글꼴] 의 경우 DW-table 에 접근하기 위한 handle.
      //DW-table 은 각각 2byte 로 구성되 있다.
      unsigned short       *DW_table;

      //{font-data} 의 handle.
      unsigned char        *fontdata;

      //[문자열 글꼴] 의 경우 [문자 헤더 테이블] handle 을 가진다.
      unsigned long long   *moonja_header_handle;
      unsigned long long    moonja_header;

      //[view]
      //{
          //-------------------------------
          RGBTRIPLE        *line_ptr;

          int               x, y;
          int               bit_val   = 0;
          //-------------------------------
      //}

      //실제 margin 이 적용된 문자 출력 영역.
      int                   box_width, box_height;

      //순수 [문자] 출력 좌표.
      int                   mX, mY;

      int                   i;

      bool                  is_CRLF = false;
  //}

  //[문자 출력 위치 X offset 적용]
  //{
      //-----------------------------------
      //출력 좌표 X 의 offset 을 적용한다.
      pX += pFONTPACK->margin_size;
      //-----------------------------------
  //}

  //[CRLF 처리]
  //{
      //-----------------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 가 없는 것이므로 일단 [공백] 으로 대체한다.
      //단지 정보를 얻기 위한 것으로 이 함수 중간의 해당 처리부에서 정보를 얻기 위하여 필요하다.
      //이 [문자] 는 실제 출력되지는 않으며, 각각의 해당 처리 함수에서 해당 하지 않는 code 로
      //인하여 return(fasle)  로 처리되는 것을 막기 위한 것이다.
      if(pCODE == 0x0d0a)
      {
        pCODE   = ' ';
        is_CRLF = true;
      }
      //-----------------------------------------------------------------------------------------
  //}


  //[문자 위치 얻기]
  //{
      //-----------------------------------------------------------------------------------------------------------------------
      //출력할 문자의 {font-data} 상의 위치를 얻는다.
      //동시에 [문자헤더] 에 접근할 경우를 위하여 [문자순번] 도 같이 얻는다.
      //이 정보는 [가변폭 글꼴] 인 경우 [문자헤더] 안의 DW 값을 얻는데 필요하다.

      //[중요수정!!!][2007.01.15.월]
      //{
          //'똠' 등의 문자가 입력되는 경우, KS5601 완성형에서는 지원하지 않으므로 자동으로 [조합형코드] 로 OS 가 바뀌어 주는데
          //이 [조합형코드] 는 지원하고 있지 않으므로 FONT_Get_MoonjaPtr_byCODE() 함수에서 false 가 된다.
          //이 경우 문자가 출력되지 못하고 종료되므로 이를 막기 위하여 해당하지 않는 코드의 경우는 무조건
          //[KS-기호] 중의 스폰지모양의 사각형을 출력하는 문자코드 0xa2c6 으로 코드르 바꾸어 주어 다시
          //FONT_Get_MoonjaPtr_byCODE() 함수를 호출하여 이 문자를 출력하는 것으로 한다.
          //이런 문제는 반드시 [한글] 등의 2 byte 문자에서 발생하므로 같은 2 byte 문자코드인 0xa2c6 으로
          //바꾸는 것이 보기도 좋고 확실하다. ? 등으로 바꾸는 경우는 혼동을 일으킬수 있다.
      //}

      ETC_MOONJA:

      if(FONT_Get_MoonjaPtr_byCODE(pFONTPACK, pCODE, &font_index, &moonja_order, &index_byte, &index_bit) != true)
      {
        //없는 코드 문자로 대체한다.
        pCODE = 0xa2c6; //▒ 문자가 해당한다.

        //바뀐 코드로 다시 처리한다.
        goto ETC_MOONJA;

      }

      //[글꼴] 관리주소를 얻는다.
      font = pFONTPACK->gft[font_index];
      //-----------------------------------------------------------------------------------------------------------------------
  //}

  //[글꼴정보]
  //{
      //------------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header   = (unsigned int *)font;

      //가로, 세로 크기를 구한다.
      width    = ENDIAN_BigToLittle_4(header[d_HEADER_width_ix]);
      height   = ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);
      option   = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);

      //{font-data} 가 시작되는 handle 을 얻는다.
      fontdata = (unsigned char *)(&(font[ENDIAN_BigToLittle_4(header[d_HEADER_dataindex_ix])]));
      //------------------------------------------------------------------------------------------
  //}

  //[DW 값 구하기]
  //{
      //[설명]{----------------------------------------------------------------
      //출력폭을 결정하는 DW 값을 얻는다.
      //[기본 글꼴]
      //=>[고정폭] : [글꼴 헤더] 의 DW 값을 바로 사용하면 된다.
      //=>[가변폭] : [DW-table] 의 해당 문자 order 의 DW 값을 사용한다.
      //
      //[문자열 글꼴]
      //[문자열 글꼴] 은 [고정/가변폭] 에 상관없이 각각의 [문자헤더] 안에 모든
      //정보가 있므으로 각각의 [문자헤더] 안의 DW 값을 사용한다.
      //}----------------------------------------------------------------------

      switch((option >> d_LANGUAGE_default_string_bt) & 0x00000001)
      {
        case d_default_bv : //[기본 글꼴]
        {
          //[고정/가변 글꼴] 에 따라서 DW 정보 위치가 달라지므로 구분하여 처리한다.
          switch((option >> d_LANGUAGE_fixed_variable_bt) & 0x00000001)
          {
            case d_fixed_bv    : //[고정폭 글꼴]
            {
              //[고정폭] 인 경우는 [글꼴 헤더] 안의 DW 기본 값을 사용하면된다.
              DW = ENDIAN_BigToLittle_4(header[d_HEADER_DWinfo_ix]);

            } break;

            case d_variable_bv : //[가변폭 글꼴]
            {
              //[가변폭] 인 경우는 DW-table(2byte 단위) 에서 지금 문자의 DW 값을 추출한다.
              //Big-Endian 으로 되 있으므로 변환처리한다.

              //DW-table 의 handle 을 얻는다.
              DW_table = (unsigned short *)(&(((unsigned int *)font)[d_HEADER_table_ix]));

              //현 문자의 DW 값을 얻는다.
              DW = ENDIAN_BigToLittle_2(DW_table[moonja_order]);

            } break;

          }

        } break;

        case d_string_bv  : //[문자열 글꼴]
        {
          //[문자 헤더 구조][64bit]{---------------------------
          //{   DW   } + {byte 위치} + {bit 위치} + {  code  }
          // .[63:51]     .[50:19]      .[18:16]     .[15:0]
          //   13bit        32bit         3bit         16bit
          //  x : byte 크기.
          // .x : bit 번호.
          //}--------------------------------------------------

          //해당 문자의 [문자 헤더] 의 DW 값을 추출한다.

          //[문자열 글꼴] 의 [문자 헤더 테이블] 위치를 얻는다.
          moonja_header_handle = (unsigned long long *)(&(header[d_HEADER_table_ix]));

          //문자의 [문자 헤더] 정보를 구한다.
          moonja_header = ENDIAN_BigToLittle_8(moonja_header_handle[moonja_order]);

          //DW 값을 구한다. ([문자열 글꼴] 에서는 13bit 크기를 갖는다.)
          DW = (moonja_header >> 51) & 0x1fff;

        } break;

      }    
  //}

  //[출력 영역 정보][이전안!!!]
  //{
      //[2010.01.25.월][주석처리!!!]
      /*
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;
      box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

      //순수 [문자] 출력 좌표 구하기.
      mX = pX + pFONTPACK->offset_left;
      mY = pY + pFONTPACK->offset_top;
      */
  //}

  //[출력 영역 정보]
  //{
      //[!]{------------------------------------------
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      //}---------------------------------------------

      //[문자 출력 폭 계산]
      //{
          //[2010.01.25.월][중요수정!!!]{-----------------------------------------------
          //[영문] 의 경우는 미리 지정한 전용 [왼쪽/오른쪽 여백] 을 추가해 주어야 한다.
          //[영문글꼴] [글꼴묶음] 의 index[3, 7] 에 해당한다.
          //}---------------------------------------------------------------------------

          if((font_index == 3) || (font_index == 7))
          {
            //[영문글꼴] 인 경우.

            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right +
                         pFONTPACK->en_offset_left + pFONTPACK->en_offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

            //순수 [문자] 출력 좌표 구하기.
            mX = pX + pFONTPACK->offset_left + pFONTPACK->en_offset_left;
            mY = pY + pFONTPACK->offset_top;

          }
          else
          {
            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

            //순수 [문자] 출력 좌표 구하기.
            mX = pX + pFONTPACK->offset_left;
            mY = pY + pFONTPACK->offset_top;

          }

      //}

  //}

  //[CRLF 처리]
  //{
      //-------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 를 출력하지 않고 행을 바꿀 정보만 반환한다.
      if(is_CRLF == true)
      {
        //----------------------------
        //[문자] 출력 영역 정보 반환.
        (*rWIDTH)  = box_width;
        (*rHEIGHT) = box_height;
        //----------------------------

        return(true);

      }
      //-------------------------------------------------------------------------------
  //}

  //[출력유효영역검사][2007.01.19.금][추가!!!]
  //{
      //실제 영역안에만 문자가 출력 되도록 영역을 검사한다.
      if(!(((0 - box_width)  <= pX) && (pX <= (bmp->Width  + box_width)) &&
           ((0 - box_height) <= pY) && (pY <= (bmp->Height + box_height))))
      {
        //[문자] 출력 영역 정보는 반드시 반환해야 한다.
        (*rWIDTH)  = box_width;
        (*rHEIGHT) = box_height;

        //출력 영역을 벗어나는 경우는 처리하지 않는다.
        return(true);

      }
  //}

  //[문자 출력]
  //{
      //----------------------------------------------------------------------
      //DW 정보를 바탕으로 문자를 지정 영역에 표시한다.
      //[문자] 를 출력할때 margin 영역의 경우도 같이 처리한다.
      //즉, 전체 box 에서 [문자] 영역은 {font-data} 를 처리하고 margin 영역은
      //[문자 배경색] 으로 칠해주면 된다.
      //----------------------------------------------------------------------

      //[왼쪽->오른쪽] && [위->아래] 로 재생해준다.
      for(y = pY; y < (pY + box_height); y++)
      {
        if((0 <= y) && (y < bmp->Height))
        {
          //[line_ptr]{-----------------------------
          //[행] 의 pointer 를 얻는다.
          line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
          //}---------------------------------------
        }
        else
        {
          line_ptr = NULL;

          //[주의!!!]{--------------------------------------------------------------------
          //[문자 한개] 의 경우도 [출력 경계선] 에 걸릴수 있으므로 여기서 바로 break 하면
          //표시 영역에 있는 문자의 "나머지 부분" 이 출력되지 않는다.
          //그러므로, 여기서 break 를 사용하여 종료하지 않아야 한다.
          //}-----------------------------------------------------------------------------
        }

        for(x = pX; x < (pX + box_width); x++)
        {
          //----------------------------------------------------------------------
          //[문자] 영역인지 [margin] 영역인지 구분하여 처리한다.
          //일단, [문자] 영역에 해당하지 않는 경우는 전부 [margin] 영역으로 본다.
          //DW 폭에 한하여 표시해야 한다.
          //----------------------------------------------------------------------

          if(((mX <= x) && (x < (mX + DW))) &&
             ((mY <= y) && (y < (mY + height))))
          {
            //[font-data 출력 영역]

            //[font-data]{----------------------------------------
            bit_val = (fontdata[index_byte] >> index_bit) & 0x01;
            //}---------------------------------------------------

            //문자색.
            if(bit_val == 1) { color = pMOONJAcolor; }
            //바탕색.
            else             { color = pBACKcolor;   }

            if((0 <= x) && (x < bmp->Width))
            {
              if((line_ptr != NULL) && (!((bit_val == 0) && (pBACKtransparent == true)))) 
              {
                //[pixel color]{------------------------------
                line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                //}-------------------------------------------
              }

            }

            //[index 수정]
            //{
                //---------------------------
                if(index_bit == 0)
                {
                  //새로운 byte 를 시작한다.
                  index_byte++;
                  //bit 초기화.
                  index_bit = 7;

                }
                else
                {
                  index_bit--;

                }
                //---------------------------
            //}

            //현 행의 [문자] 의 마지막 bit 를 처리한 상태라면...
            //반드시 이 위치에서 처리되어야 한다.
            if(x == (mX + DW - 1))
            {
              //[{font-data} 소진]{-----------------------------------------------
              //"0 - width" 까지 사용되지 않은 이 행의 남은 {font-data} 를 여기서
              //완전히 소진해 주어야 한다.
              //(width - DW) 크기가 아직 남아 있다.
              //}-----------------------------------------------------------------

              for(i = 0; i < (width - DW); i++)
              {
                //[index 수정]
                //{
                    //---------------------------
                    if(index_bit == 0)
                    {
                      //새로운 byte 를 시작한다.
                      index_byte++;
                      //bit 초기화.
                      index_bit = 7;

                    }
                    else
                    {
                      index_bit--;

                    }
                    //---------------------------
                //}
              }

            }

          }
          else
          {
            //이 경우는 margin 영역에 들어 있는 겻이므로 [문자 배경색] 으로 칠한다.
            color = pBACKcolor;

            if((0 <= x) && (x < bmp->Width))
            {
              if((line_ptr != NULL) && (!((bit_val == 0) && (pBACKtransparent == true))))
              {
                //[pixel color]{------------------------------
                line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                //}-------------------------------------------
              }

            }

          }

        }

      }
  //}

  //[underline]
  //{
      //[공백 검사]{----------------------------------
      //[공백] 문자인 경우는 결정에 따른다.
      if((pUNDERLINEspace != true) && (pCODE == ' '))
      {
        goto END;

      }
      //}---------------------------------------------

      //지정된 [설정] 에 따라 문자 아래에 밑줄을 그어준다.
      switch(pUNDERLINEkind)
      {
        case  d_FONT_underline_no :
        {
          //아무 처리도 하지 않는다.

        } break;

        case  d_FONT_underline_dot :
        {
          //101010 의 형식으로 1 pixel 단위로 dot 를 찍어 준다.
          y = pY + (box_height - 1) + pUNDERLINEoffset;

          if((0 <= y) && (y < bmp->Height))
          {
            //[line_ptr]{-----------------------------
            //[행] 의 pointer 를 얻는다.
            line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
            //}---------------------------------------

            color = pUNDERLINEcolor;

            for(x = pX, i = 0; x < (pX + box_width); x++, i++)
            {
              if((i % 2) == 0)
              {
                //dot 를 지정색으로 찍어 준다.

                if((0 <= x) && (x < bmp->Width))
                {
                  if(line_ptr != NULL)
                  {
                    //[pixel color]{------------------------------
                    line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                    line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                    line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                  //}-------------------------------------------
                  }
                }
              }
            }
          }
          else
          {
            line_ptr = NULL;

          }

        } break;

        case  d_FONT_underline_dot2 :
        {
          //101010 의 형식으로 1 pixel 단위로 dot 를 찍어 준다.
          y = pY + (box_height - 1) + pUNDERLINEoffset;

          if((0 <= y) && (y < bmp->Height))
          {
            //[line_ptr]{-----------------------------
            //[행] 의 pointer 를 얻는다.
            line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
            //}---------------------------------------

            color = pUNDERLINEcolor;

            for(x = pX, i = 1; x < (pX + box_width); x++, i++)
            {
              if((i % 3) != 0)
              {
                //dot 를 지정색으로 찍어 준다.

                if((0 <= x) && (x < bmp->Width))
                {
                  if(line_ptr != NULL)
                  {
                    //[pixel color]{------------------------------
                    line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                    line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                    line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                    //}-------------------------------------------
                  }
                }
              }
            }
          }
          else
          {
            line_ptr = NULL;

          }

        } break;

        case  d_FONT_underline_line :
        {
          //선으로 긋는다.

          y = pY + (box_height - 1) + pUNDERLINEoffset;

          if((0 <= y) && (y < bmp->Height))
          {
            //[line_ptr]{-----------------------------
            //[행] 의 pointer 를 얻는다.
            line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
            //}---------------------------------------

            color = pUNDERLINEcolor;

            for(x = pX, i = 0; x < (pX + box_width); x++, i++)
            {
              //line 을 그리므로 전부 찍어준다.

              if((0 <= x) && (x < bmp->Width))
              {
                if(line_ptr != NULL)
                {
                  //[pixel color]{------------------------------
                  line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                  line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                  line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                  //}-------------------------------------------
                }
              }
            }
          }
          else
          {
            line_ptr = NULL;

          }

        } break;
      }
  //}

  END:

  //[반환]
  //{
      //----------------------------
      //[문자] 출력 영역 정보 반환.
      (*rWIDTH)  = box_width;
      (*rHEIGHT) = box_height;
      //----------------------------
  //}

  return(true);

}

bool __fastcall FONT_Out_String2(//[문자] 를 출력할 bitmap handle.
                                 Graphics::TBitmap  *pVIEWhandle,
                                 //[사용 글꼴 묶음].
                                 struct FONTPACK    *pFONTPACK,
                                 //문자열을 출력할 시작 위치.(BASE:0)
                                 int                 pX,
                                 int                 pY,
                                 //문자색.
                                 int                 pMOONJAcolor,
                                 //배경색.
                                 int                 pBACKcolor,
                                 //배경색투명속성지정.
                                 bool                pBACKtransparent,
                                 //출력할 문자열.
                                 char               *pSTRING,
                                 //[field option]--------------------------------
                                 //밑줄 종류.
                                 int                 pUNDERLINEkind,
                                 //[공백] 에도 적용할지여부.
                                 bool                pUNDERLINEspace,
                                 //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                 int                 pUNDERLINEoffset,
                                 //밑줄 색.
                                 int                 pUNDERLINEcolor,
                                 //----------------------------------------------
                                 //문자열 출력후 변경된 (x, y) 좌표를 반환한다.
                                 int                *rX,
                                 int                *rY)
{
  //[2006.10.07.토][생성!!!]{-----------------------------------------------
  //문자열을 전달 받아서 지정 위치에 출력한다.
  //단, 반드시 "CR/LF" "0Dh/0Ah"도 완벽하게 지원해야 한다.(순서대로)
  //<tab> 은 지원하지 않으므로 만약 발견 된다면 공백으로 대치하여 처리한다.
  //실제 에디터 상에서는 아예 <tab> 을 지원하지 않는다.
  //사용하는 경우는 역시 공백으로 처리한다.
  //}-----------------------------------------------------------------------

  //[중요!!!]
  //{
      //-----------------------------------------------------------------------
      //[문자] [좌/우 공백] 의 경우는 글꼴을 사용하는 프로그램에서 [옵션] 으로
      //지정되는 것으로 이 함수를 사용하는 곳에서 이 [옵션] 을 적용하여 pX, pY
      //값을 지정해 주는 것으로 처리해야 한다.
      //이 [설정] 은 [글꼴 묶음] 안에 포함되 있다.
      //-----------------------------------------------------------------------
  //}

  //[2006.11.01.수][추가!!!]
  //{
      //---------------------------------------------------------------------------
      //문자가 출력 영역에 위치하는 지만 검사하는 경우는 문서량이 많은 경우
      //모든 문자를 다 처리하게 되므로 처리 시간이 많이 결린다.
      //이를 막기 위하여 [표시영역] 정보를 바탕으로 출력되는 행의 범위를 구하여
      //이 범위 안에 해당하는 문서행만 출력하고 나머지는 아예 처리하지 않도록한다.
      //이렇게 하면, 아무리 문서량이 많아도 표시 영역에 해당하는 행만 출력하므로
      //문서 량에 따라 처리 속도가 거의 차이가 없게 된다.
      //---------------------------------------------------------------------------
  //}

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             box_width, box_height;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //[출력행계산관련]
      //{
          //현재 출력하는 문서의 행번호.
          int         line_number = 0;

          //문자 출력 행의 높이.
          int         line_height;
          //출력 시작 행 번호(BASE:0)
          int         doc_line_start;
          //출력 끝 행 번호(BASE:0)
          int         doc_line_end;
      //}
  //}

  //[출력 행 정보 계산]
  //{
      //[행높이 구하기]{------------------------------------------------------------------------------------------------
      //[글꼴] 의 크기를 알기 위한 CRLF 문자 출력.
      FONT_Out_Moonja(pVIEWhandle, pFONTPACK, 0, 0, pMOONJAcolor, pBACKcolor, false, 0x0d0a, &box_width, &line_height);
      //----------------------------------------------------------------------------------------------------------------

      //[설명!!!]{------------------------------------------------------
      //출력 행의 범위를 계산한다.
      //여기서 "행" 은 "문서" 의 행을 말한다.(출력 영역의 행이 아니다.)
      //여기서 구한 두행 사이의 문서행만 실제로 출력하게 된다.
      //}---------------------------------------------------------------

      if(pY < 0)
      {
        //출력 시작 위치가 [음수] 인 경우, [음수 영역] 은 출력대상이 되지 않는다.

        //[출력 시작 행]
        doc_line_start = ((-1) * pY) / line_height;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
      else
      {
        //표시영역안은 항상 문서의 0 행부터 출력하면 된다.

        //[출력 시작 행]
        doc_line_start = 0;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      //[앞선 무효영역 제거]
      //{
          //doc_line_start 보다 작은 행은 표시할 필요가 없으므로 CRLF 를 찾아서
          //doc_line_start 행의 첫 문자의 위치를 찾아서 여기서 부터 출력한다.

          for(i = 0, line_number = 0;
              //[문자열] 끝이 나올때 까지 처리한다.
              pSTRING[i] != '\0';
             )
          {
            //처음행은 CRLF 전에 위치하므로 여기서 먼저 행을 검사한다.
            if(line_number == doc_line_start)
            {
              //출력으르 시작할 문서의 행을 얻었으므로 다음 처리로 들어간다.
              break;

            }

            if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
            {
              //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

              //다음 행의 좌표로 수정한다.
              pX  = 0;
              pY += line_height;

              i  += 2;

              //다음 행번호를 지정한다.
              line_number++;

            }
            else
            {
              i++;

            }

          }
      //}

      for(/*위에서 계속되는 값을 사용한다.*/;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pSTRING[i] != '\0';
         )
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }
        else if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
        {
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //다음 행의 좌표로 수정한다.
          pX  = 0;
          pY += box_height;

          i += 2;

          //다음 행번호를 지정한다.
          line_number++;

          if(!(line_number <= doc_line_end))
          {
            //처리행을 넘었으므로 더이상 처리하지 않는다.
            goto END;

          }

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }

      }
  //}

  END:

  (*rX) = pX;
  (*rY) = pY;

  return(true);

}

bool __fastcall FONT_Out_StyleMoonja(//[문자] 를 출력할 bitmap handle.
                                     Graphics::TBitmap  *pVIEWhandle,
                                     //[사용 글꼴 묶음].
                                     struct FONTPACK    *pFONTPACK,
                                     //문자를 표시할 좌표.(BASE:0)
                                     int                 pX,
                                     int                 pY,
                                     //문자색.
                                     int                 pMOONJAcolor,
                                     //배경색.
                                     int                 pBACKcolor,
                                     //배경색투명속성지정.
                                     bool                pBACKtransparent,
                                     //문자출력형식지정.(기본글꼴/굵은글꼴...)
                                     int                 pSTYLE,
                                     //출력 문자 코드.
                                     unsigned short      pCODE,
                                     //[field option]--------------------------------
                                     //밑줄 종류.
                                     int                 pUNDERLINEkind,
                                     //[공백] 에도 적용할지여부.
                                     bool                pUNDERLINEspace,
                                     //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                     int                 pUNDERLINEoffset,
                                     //밑줄 색.
                                     int                 pUNDERLINEcolor,
                                     //----------------------------------------------
                                     //출력된 문자 width, height 정보 반환.
                                     int                *rWIDTH,
                                     int                *rHEIGHT)
{
  //[2007.02.05.월][생성!!!]{------------------------------------------------------------
  //FONT_Out_Moonja2() 함수에 기능을 추가한 함수이다.
  //이 함수는 [기본글꼴/굵은글꼴] 등을 지정할수 있다.
  //즉, [출력형식] 을 정의 할수 있다.(단, [기울임글꼴] 은 아직 지원하지 않는다.)

  //[기본글꼴 index + 4(d_FONTSTYLE_bold)] 의 경우 자동으로 같은 글꼴의 [굵은글꼴 index]
  //위치가 된다.
  //d_FONTSTYLE_bold 는 이미 정의된 값이므로 바로 더하여 사용할수 있다.
  //}------------------------------------------------------------------------------------

  //[VAR]
  //{
      //표시할 영역 handle.
      Graphics::TBitmap    *bmp = pVIEWhandle;

      //사용할 [글꼴].
      unsigned char        *font;
      int                   font_index;

      //*.gft 파일의 header handle 을 얻는다.
      unsigned int         *header;

      //출력할 [문자] 의 [순번].
      int                   moonja_order;

      //출력할 [문자] 의 {font-data} 상위 위치.
      int                   index_byte, index_bit;

      //글꼴 정보.
      int                   width, height;
      unsigned int          option;
      int                   DW;
      int                   color;

      //[기본:가변 글꼴] 의 경우 DW-table 에 접근하기 위한 handle.
      //DW-table 은 각각 2byte 로 구성되 있다.
      unsigned short       *DW_table;

      //{font-data} 의 handle.
      unsigned char        *fontdata;

      //[문자열 글꼴] 의 경우 [문자 헤더 테이블] handle 을 가진다.
      unsigned long long   *moonja_header_handle;
      unsigned long long    moonja_header;

      //[view]
      //{
          //-------------------------------
          RGBTRIPLE        *line_ptr;

          int               x, y;
          int               bit_val   = 0;
          //-------------------------------
      //}

      //실제 margin 이 적용된 문자 출력 영역.
      int                   box_width, box_height;

      //순수 [문자] 출력 좌표.
      int                   mX, mY;

      int                   i;

      bool                  is_CRLF = false;
  //}

  //[문자 출력 위치 X offset 적용]
  //{
      //-----------------------------------
      //출력 좌표 X 의 offset 을 적용한다.
      pX += pFONTPACK->margin_size;
      //-----------------------------------
  //}

  //[CRLF 처리]
  //{
      //-----------------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 가 없는 것이므로 일단 [공백] 으로 대체한다.
      //단지 정보를 얻기 위한 것으로 이 함수 중간의 해당 처리부에서 정보를 얻기 위하여 필요하다.
      //이 [문자] 는 실제 출력되지는 않으며, 각각의 해당 처리 함수에서 해당 하지 않는 code 로
      //인하여 return(fasle)  로 처리되는 것을 막기 위한 것이다.
      if(pCODE == 0x0d0a)
      {
        pCODE   = ' ';
        is_CRLF = true;

      }
      //-----------------------------------------------------------------------------------------
  //}


  //[문자 위치 얻기]
  //{
      //-----------------------------------------------------------------------------------------------------------------------
      //출력할 문자의 {font-data} 상의 위치를 얻는다.
      //동시에 [문자헤더] 에 접근할 경우를 위하여 [문자순번] 도 같이 얻는다.
      //이 정보는 [가변폭 글꼴] 인 경우 [문자헤더] 안의 DW 값을 얻는데 필요하다.

      //[중요수정!!!][2007.01.15.월]
      //{
          //'똠' 등의 문자가 입력되는 경우, KS5601 완성형에서는 지원하지 않으므로 자동으로 [조합형코드] 로 OS 가 바뀌어 주는데
          //이 [조합형코드] 는 지원하고 있지 않으므로 FONT_Get_MoonjaPtr_byCODE() 함수에서 false 가 된다.
          //이 경우 문자가 출력되지 못하고 종료되므로 이를 막기 위하여 해당하지 않는 코드의 경우는 무조건
          //[KS-기호] 중의 스폰지모양의 사각형을 출력하는 문자코드 0xa2c6 으로 코드르 바꾸어 주어 다시
          //FONT_Get_MoonjaPtr_byCODE() 함수를 호출하여 이 문자를 출력하는 것으로 한다.
          //이런 문제는 반드시 [한글] 등의 2 byte 문자에서 발생하므로 같은 2 byte 문자코드인 0xa2c6 으로
          //바꾸는 것이 보기도 좋고 확실하다. ? 등으로 바꾸는 경우는 혼동을 일으킬수 있다.
      //}

      ETC_MOONJA:

      if(FONT_Get_MoonjaPtr_byCODE(pFONTPACK, pCODE, &font_index, &moonja_order, &index_byte, &index_bit) != true)
      {
        //없는 코드 문자로 대체한다.
        pCODE = 0xa2c6; //▒ 문자가 해당한다.

        //바뀐 코드로 다시 처리한다.
        goto ETC_MOONJA;

      }
      //-----------------------------------------------------------------------------------------------------------------------
  //}

  //[글꼴 출력 형식 구분]
  //{
      //출력 형식에 따른 해당 글꼴의 관리주소값을 얻는다.

      switch(pSTYLE)
      {
        case d_FONTSTYLE_default :
        {
          //[기본형식 출력]

          //기본값을 그대로 사용하면 된다.
          font = pFONTPACK->gft[font_index];

        } break;

        case d_FONTSTYLE_bold :
        {
          //[굵은글꼴 출력]

          //현재 + 4 의 index 위치가 이 글꼴의 [굵은글꼴] 이 된다.
          font = pFONTPACK->gft[font_index + d_FONTSTYLE_bold] ;

          //[문자 자료 시작 위치 얻기]
          //{
              //[2010.01.30.토][중요추가!!!]{--------------------------------------------------------
              //바로 위 FONT_Get_MoonjaPtr_byCODE() 에서 얻는 정보는 기본적으로 [보통글꼴] 인 경우의
              //정보이므로 [굵은글꼴] 의 경우로 [글꼴] 이 변경된 경우는 다시 해당 글꼴에 맞게
              //정보를 다시 얻어야 한다.
              //즉, <index_byte> 와 <index_bit> 두개 정보를 정확한 글꼴로 새로 얻기 위한 것이다.
              //}------------------------------------------------------------------------------------

              FONT_Get_MoonjaPtr_byORDER(font, moonja_order, &index_byte, &index_bit);

          //}

        } break;

      }

  //}

  //[글꼴정보]
  //{
      //------------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header   = (unsigned int *)font;

      //가로, 세로 크기를 구한다.
      width    = ENDIAN_BigToLittle_4(header[d_HEADER_width_ix]);
      height   = ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);

      option   = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);

      //{font-data} 가 시작되는 handle 을 얻는다.
      fontdata = (unsigned char *)(&(font[ENDIAN_BigToLittle_4(header[d_HEADER_dataindex_ix])]));
      //------------------------------------------------------------------------------------------
  //}

  //[DW 값 구하기]
  //{
      //[설명]{----------------------------------------------------------------
      //출력폭을 결정하는 DW 값을 얻는다.
      //[기본 글꼴]
      //=>[고정폭] : [글꼴 헤더] 의 DW 값을 바로 사용하면 된다.
      //=>[가변폭] : [DW-table] 의 해당 문자 order 의 DW 값을 사용한다.
      //
      //[문자열 글꼴]
      //[문자열 글꼴] 은 [고정/가변폭] 에 상관없이 각각의 [문자헤더] 안에 모든
      //정보가 있므으로 각각의 [문자헤더] 안의 DW 값을 사용한다.
      //}----------------------------------------------------------------------

      switch((option >> d_LANGUAGE_default_string_bt) & 0x00000001)
      {
        case d_default_bv : //[기본 글꼴]
        {
          //[고정/가변 글꼴] 에 따라서 DW 정보 위치가 달라지므로 구분하여 처리한다.
          switch((option >> d_LANGUAGE_fixed_variable_bt) & 0x00000001)
          {
            case d_fixed_bv    : //[고정폭 글꼴]
            {
              //[고정폭] 인 경우는 [글꼴 헤더] 안의 DW 기본 값을 사용하면된다.
              DW = ENDIAN_BigToLittle_4(header[d_HEADER_DWinfo_ix]);

            } break;

            case d_variable_bv : //[가변폭 글꼴]
            {
              //[가변폭] 인 경우는 DW-table(2byte 단위) 에서 지금 문자의 DW 값을 추출한다.
              //Big-Endian 으로 되 있으므로 변환처리한다.

              //DW-table 의 handle 을 얻는다.
              DW_table = (unsigned short *)(&(((unsigned int *)font)[d_HEADER_table_ix]));

              //현 문자의 DW 값을 얻는다.
              DW = ENDIAN_BigToLittle_2(DW_table[moonja_order]);

            } break;

          }

        } break;

        case d_string_bv  : //[문자열 글꼴]
        {
          //[문자 헤더 구조][64bit]{---------------------------
          //{   DW   } + {byte 위치} + {bit 위치} + {  code  }
          // .[63:51]     .[50:19]      .[18:16]     .[15:0]
          //   13bit        32bit         3bit         16bit
          //  x : byte 크기.
          // .x : bit 번호.
          //}--------------------------------------------------

          //해당 문자의 [문자 헤더] 의 DW 값을 추출한다.

          //[문자열 글꼴] 의 [문자 헤더 테이블] 위치를 얻는다.
          moonja_header_handle = (unsigned long long *)(&(header[d_HEADER_table_ix]));

          //문자의 [문자 헤더] 정보를 구한다.
          moonja_header = ENDIAN_BigToLittle_8(moonja_header_handle[moonja_order]);

          //DW 값을 구한다. ([문자열 글꼴] 에서는 13bit 크기를 갖는다.)
          DW = (moonja_header >> 51) & 0x1fff;

        } break;

      }

  //}

  //[출력 영역 정보][이전안!!!]
  //{
      //[2010.01.25.월][주석처리!!!]
      /*
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;
      box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

      //순수 [문자] 출력 좌표 구하기.
      mX = pX + pFONTPACK->offset_left;
      mY = pY + pFONTPACK->offset_top;
      */
  //}

  //[출력 영역 정보]
  //{
      //[!]{------------------------------------------
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      //}---------------------------------------------

      //[문자 출력 폭 계산]
      //{
          //[2010.01.25.월][중요수정!!!]{-----------------------------------------------
          //[영문] 의 경우는 미리 지정한 전용 [왼쪽/오른쪽 여백] 을 추가해 주어야 한다.
          //[영문글꼴] [글꼴묶음] 의 index[3, 7] 에 해당한다.
          //}---------------------------------------------------------------------------

          if((font_index == 3) || (font_index == 7))
          {
            //[영문글꼴] 인 경우.

            box_width  = DW     + pFONTPACK->offset_left    + pFONTPACK->offset_right +
                                  pFONTPACK->en_offset_left + pFONTPACK->en_offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

            //순수 [문자] 출력 좌표 구하기.
            mX = pX + pFONTPACK->offset_left + pFONTPACK->en_offset_left;
            mY = pY + pFONTPACK->offset_top;

          }
          else
          {
            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

            //순수 [문자] 출력 좌표 구하기.
            mX = pX + pFONTPACK->offset_left;
            mY = pY + pFONTPACK->offset_top;

          }

      //}

  //}

  //[CRLF 처리]
  //{
      //-------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 를 출력하지 않고 행을 바꿀 정보만 반환한다.
      if(is_CRLF == true)
      {
        //----------------------------
        //[문자] 출력 영역 정보 반환.
        (*rWIDTH)  = box_width;
        (*rHEIGHT) = box_height;
        //----------------------------

        return(true);

      }
      //-------------------------------------------------------------------------------
  //}

  //[출력유효영역검사][2007.01.19.금][추가!!!]
  //{
      //실제 영역안에만 문자가 출력 되도록 영역을 검사한다.
      if(!(((0 - box_width)  <= pX) && (pX <= (bmp->Width  + box_width)) &&
           ((0 - box_height) <= pY) && (pY <= (bmp->Height + box_height))))
      {
        //[문자] 출력 영역 정보는 반드시 반환해야 한다.
        (*rWIDTH)  = box_width;
        (*rHEIGHT) = box_height;

        //출력 영역을 벗어나는 경우는 처리하지 않는다.
        return(true);

      }
  //}

  //[문자 출력]
  //{
      //----------------------------------------------------------------------
      //DW 정보를 바탕으로 문자를 지정 영역에 표시한다.
      //[문자] 를 출력할때 margin 영역의 경우도 같이 처리한다.
      //즉, 전체 box 에서 [문자] 영역은 {font-data} 를 처리하고 margin 영역은
      //[문자 배경색] 으로 칠해주면 된다.
      //----------------------------------------------------------------------

      //[왼쪽->오른쪽] && [위->아래] 로 재생해준다.
      for(y = pY; y < (pY + box_height); y++)
      {
        if((0 <= y) && (y < bmp->Height))
        {
          //[line_ptr]{-----------------------------
          //[행] 의 pointer 를 얻는다.
          line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
          //}---------------------------------------
        }
        else
        {
          line_ptr = NULL;

          //[주의!!!]{--------------------------------------------------------------------
          //[문자 한개] 의 경우도 [출력 경계선] 에 걸릴수 있으므로 여기서 바로 break 하면
          //표시 영역에 있는 문자의 "나머지 부분" 이 출력되지 않는다.
          //그러므로, 여기서 break 를 사용하여 종료하지 않아야 한다.
          //}-----------------------------------------------------------------------------
        }

        for(x = pX; x < (pX + box_width); x++)
        {
          //----------------------------------------------------------------------
          //[문자] 영역인지 [margin] 영역인지 구분하여 처리한다.
          //일단, [문자] 영역에 해당하지 않는 경우는 전부 [margin] 영역으로 본다.
          //DW 폭에 한하여 표시해야 한다.
          //----------------------------------------------------------------------

          if(((mX <= x) && (x < (mX + DW))) &&
             ((mY <= y) && (y < (mY + height))))
          {
            //[font-data 출력 영역]

            //[font-data]{----------------------------------------
            bit_val = (fontdata[index_byte] >> index_bit) & 0x01;
            //}---------------------------------------------------

            //문자색.
            if(bit_val == 1) { color = pMOONJAcolor; }
            //바탕색.
            else             { color = pBACKcolor;   }

            if((0 <= x) && (x < bmp->Width))
            {
              if((line_ptr != NULL) && (!((bit_val == 0) && (pBACKtransparent == true)))) 
              {
                //[pixel color]{------------------------------
                line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                //}-------------------------------------------
              }

            }

            //[index 수정]
            //{
                //---------------------------
                if(index_bit == 0)
                {
                  //새로운 byte 를 시작한다.
                  index_byte++;
                  //bit 초기화.
                  index_bit = 7;

                }
                else
                {
                  index_bit--;

                }
                //---------------------------
            //}

            //현 행의 [문자] 의 마지막 bit 를 처리한 상태라면...
            //반드시 이 위치에서 처리되어야 한다.
            if(x == (mX + DW - 1))
            {
              //[{font-data} 소진]{-----------------------------------------------
              //"0 - width" 까지 사용되지 않은 이 행의 남은 {font-data} 를 여기서
              //완전히 소진해 주어야 한다.
              //(width - DW) 크기가 아직 남아 있다.
              //}-----------------------------------------------------------------

              for(i = 0; i < (width - DW); i++)
              {
                //[index 수정]
                //{
                    //---------------------------
                    if(index_bit == 0)
                    {
                      //새로운 byte 를 시작한다.
                      index_byte++;
                      //bit 초기화.
                      index_bit = 7;

                    }
                    else
                    {
                      index_bit--;

                    }
                    //---------------------------
                //}
              }

            }

          }
          else
          {
            //이 경우는 margin 영역에 들어 있는 겻이므로 [문자 배경색] 으로 칠한다.
            color = pBACKcolor;

            if((0 <= x) && (x < bmp->Width))
            {
              if((line_ptr != NULL) && (!((bit_val == 0) && (pBACKtransparent == true))))
              {
                //[pixel color]{------------------------------
                line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                //}-------------------------------------------
              }

            }

          }

        }

      }
  //}

  //[underline]
  //{
      //[공백 검사]{----------------------------------
      //[공백] 문자인 경우는 결정에 따른다.
      if((pUNDERLINEspace != true) && (pCODE == ' '))
      {
        goto END;

      }
      //}---------------------------------------------

      //지정된 [설정] 에 따라 문자 아래에 밑줄을 그어준다.
      switch(pUNDERLINEkind)
      {
        case  d_FONT_underline_no :
        {
          //아무 처리도 하지 않는다.

        } break;

        case  d_FONT_underline_dot :
        {
          //101010 의 형식으로 1 pixel 단위로 dot 를 찍어 준다.
          y = pY + (box_height - 1) + pUNDERLINEoffset;

          if((0 <= y) && (y < bmp->Height))
          {
            //[line_ptr]{-----------------------------
            //[행] 의 pointer 를 얻는다.
            line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
            //}---------------------------------------

            color = pUNDERLINEcolor;

            for(x = pX, i = 0; x < (pX + box_width); x++, i++)
            {
              if((i % 2) == 0)
              {
                //dot 를 지정색으로 찍어 준다.

                if((0 <= x) && (x < bmp->Width))
                {
                  if(line_ptr != NULL)
                  {
                    //[pixel color]{------------------------------
                    line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                    line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                    line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                  //}-------------------------------------------
                  }
                }
              }
            }
          }
          else
          {
            line_ptr = NULL;

          }

        } break;

        case  d_FONT_underline_dot2 :
        {
          //101010 의 형식으로 1 pixel 단위로 dot 를 찍어 준다.
          y = pY + (box_height - 1) + pUNDERLINEoffset;

          if((0 <= y) && (y < bmp->Height))
          {
            //[line_ptr]{-----------------------------
            //[행] 의 pointer 를 얻는다.
            line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
            //}---------------------------------------

            color = pUNDERLINEcolor;

            for(x = pX, i = 1; x < (pX + box_width); x++, i++)
            {
              if((i % 3) != 0)
              {
                //dot 를 지정색으로 찍어 준다.

                if((0 <= x) && (x < bmp->Width))
                {
                  if(line_ptr != NULL)
                  {
                    //[pixel color]{------------------------------
                    line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                    line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                    line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                    //}-------------------------------------------
                  }
                }
              }
            }
          }
          else
          {
            line_ptr = NULL;

          }

        } break;

        case  d_FONT_underline_line :
        {
          //선으로 긋는다.

          y = pY + (box_height - 1) + pUNDERLINEoffset;

          if((0 <= y) && (y < bmp->Height))
          {
            //[line_ptr]{-----------------------------
            //[행] 의 pointer 를 얻는다.
            line_ptr = (RGBTRIPLE *)bmp->ScanLine[y];
            //}---------------------------------------

            color = pUNDERLINEcolor;

            for(x = pX, i = 0; x < (pX + box_width); x++, i++)
            {
              //line 을 그리므로 전부 찍어준다.

              if((0 <= x) && (x < bmp->Width))
              {
                if(line_ptr != NULL)
                {
                  //[pixel color]{------------------------------
                  line_ptr[x].rgbtBlue  = (color >> 16) & 0xff;
                  line_ptr[x].rgbtGreen = (color >>  8) & 0xff;
                  line_ptr[x].rgbtRed   = (color >>  0) & 0xff;
                  //}-------------------------------------------
                }
              }
            }
          }
          else
          {
            line_ptr = NULL;

          }

        } break;
      }
  //}

  END:

  //[반환]
  //{
      //----------------------------
      //[문자] 출력 영역 정보 반환.
      (*rWIDTH)  = box_width;
      (*rHEIGHT) = box_height;
      //----------------------------
  //}

  return(true);

}

bool __fastcall FONT_Out_StyleString2(//[문자] 를 출력할 bitmap handle.
                                      Graphics::TBitmap  *pVIEWhandle,
                                      //[사용 글꼴 묶음].
                                      struct FONTPACK    *pFONTPACK,
                                      //문자열을 출력할 시작 위치.(BASE:0)
                                      int                 pX,
                                      int                 pY,
                                      //문자색.
                                      int                 pMOONJAcolor,
                                      //배경색.
                                      int                 pBACKcolor,
                                      //배경색투명속성지정.
                                      bool                pBACKtransparent,
                                      //문자출력형식지정.(기본글꼴/굵은글꼴...)
                                      int                 pSTYLE,
                                      //출력할 문자열.
                                      char               *pSTRING,
                                      //[field option]--------------------------------
                                      //밑줄 종류.
                                      int                 pUNDERLINEkind,
                                      //[공백] 에도 적용할지여부.
                                      bool                pUNDERLINEspace,
                                      //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                      int                 pUNDERLINEoffset,
                                      //밑줄 색.
                                      int                 pUNDERLINEcolor,
                                      //----------------------------------------------
                                      //문자열 출력후 변경된 (x, y) 좌표를 반환한다.
                                      int                *rX,
                                      int                *rY)
{
  //[2007.03.27.화][생성!!!]{-----------------------------------------------
  //FONT_Out_String2() 함수에 pSTYLE 속성을 추가하여 출력하도록 만든것이다.
  //즉, [기본글꼴/굵은글꼴] 을 지정하여 사용할수 있다.
  //}-----------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             box_width, box_height;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //[출력행계산관련]
      //{
          //현재 출력하는 문서의 행번호.
          int         line_number = 0;

          //문자 출력 행의 높이.
          int         line_height;
          //출력 시작 행 번호(BASE:0)
          int         doc_line_start;
          //출력 끝 행 번호(BASE:0)
          int         doc_line_end;
      //}
  //}

  //[출력 행 정보 계산]
  //{
      //[행높이 구하기]{------------------------------------------------------------------------------------------------
      //[글꼴] 의 크기를 알기 위한 CRLF 문자 출력.
      FONT_Out_Moonja(pVIEWhandle, pFONTPACK, 0, 0, pMOONJAcolor, pBACKcolor, false, 0x0d0a, &box_width, &line_height);
      //----------------------------------------------------------------------------------------------------------------

      //[설명!!!]{------------------------------------------------------
      //출력 행의 범위를 계산한다.
      //여기서 "행" 은 "문서" 의 행을 말한다.(출력 영역의 행이 아니다.)
      //여기서 구한 두행 사이의 문서행만 실제로 출력하게 된다.
      //}---------------------------------------------------------------

      if(pY < 0)
      {
        //출력 시작 위치가 [음수] 인 경우, [음수 영역] 은 출력대상이 되지 않는다.

        //[출력 시작 행]
        doc_line_start = ((-1) * pY) / line_height;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
      else
      {
        //표시영역안은 항상 문서의 0 행부터 출력하면 된다.

        //[출력 시작 행]
        doc_line_start = 0;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      //[앞선 무효영역 제거]
      //{
          //doc_line_start 보다 작은 행은 표시할 필요가 없으므로 CRLF 를 찾아서
          //doc_line_start 행의 첫 문자의 위치를 찾아서 여기서 부터 출력한다.

          for(i = 0, line_number = 0;
              //[문자열] 끝이 나올때 까지 처리한다.
              pSTRING[i] != '\0';
             )
          {
            //처음행은 CRLF 전에 위치하므로 여기서 먼저 행을 검사한다.
            if(line_number == doc_line_start)
            {
              //출력으르 시작할 문서의 행을 얻었으므로 다음 처리로 들어간다.
              break;

            }

            if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
            {
              //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

              //다음 행의 좌표로 수정한다.
              pX  = 0;
              pY += line_height;

              i  += 2;

              //다음 행번호를 지정한다.
              line_number++;

            }
            else
            {
              i++;

            }

          }
      //}

      for(/*위에서 계속되는 값을 사용한다.*/;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pSTRING[i] != '\0';
         )
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }
        else if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
        {
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //다음 행의 좌표로 수정한다.
          pX  = 0;
          pY += box_height;

          i += 2;

          //다음 행번호를 지정한다.
          line_number++;

          if(!(line_number <= doc_line_end))
          {
            //처리행을 넘었으므로 더이상 처리하지 않는다.
            goto END;

          }

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }

      }
  //}

  END:

  //[2012.05.28.월][수정!!!]{---
  //NULL 이 아닌 경우만 반환.
  //}---------------------------

  if(rX != NULL) { (*rX) = pX; }
  if(rY != NULL) { (*rY) = pY; }

  return(true);

}

bool __fastcall FONT_Out_StyleString3(//[문자] 를 출력할 bitmap handle.
                                      Graphics::TBitmap  *pVIEWhandle,
                                      //[사용 글꼴 묶음].
                                      struct FONTPACK    *pFONTPACK,
                                      //문자열을 출력할 시작 위치.(BASE:0)
                                      int                 pX,
                                      int                 pY,
                                      //문자색.
                                      int                 pMOONJAcolor,
                                      //배경색.
                                      int                 pBACKcolor,
                                      //배경색투명속성지정.
                                      bool                pBACKtransparent,
                                      //문자출력형식지정.(기본글꼴/굵은글꼴...)
                                      int                 pSTYLE,
                                      //출력할 문자열.
                                      char               *pSTRING,

                                      //[2010.02.19.금][추가!!!]--------
                                      //출력 [시작 문자] 위치.
                                      int                 pStartIndex,
                                      //출력 [끝 문자] 다음 문자 위치.
                                      int                 pEndIndex,

                                      //[field option]--------------------------------
                                      //밑줄 종류.
                                      int                 pUNDERLINEkind,
                                      //[공백] 에도 적용할지여부.
                                      bool                pUNDERLINEspace,
                                      //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                      int                 pUNDERLINEoffset,
                                      //밑줄 색.
                                      int                 pUNDERLINEcolor,
                                      //----------------------------------------------
                                      //문자열 출력후 변경된 (x, y) 좌표를 반환한다.
                                      int                *rX,
                                      int                *rY)
{
  //[2010.02.19.금][생성!!!]{------------------------------------------------------
  //FONT_Out_StyleString2() 함수를 수정하여 [시작위치] - [끝위치] 까지만 출력한다.
  //}------------------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             box_width, box_height;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //[출력행계산관련]
      //{
          //현재 출력하는 문서의 행번호.
          int         line_number = 0;

          //문자 출력 행의 높이.
          int         line_height;
          //출력 시작 행 번호(BASE:0)
          int         doc_line_start;
          //출력 끝 행 번호(BASE:0)
          int         doc_line_end;
      //}
  //}

  //[출력 행 정보 계산]
  //{
      //[행높이 구하기]{------------------------------------------------------------------------------------------------
      //[글꼴] 의 크기를 알기 위한 CRLF 문자 출력.
      FONT_Out_Moonja(pVIEWhandle, pFONTPACK, 0, 0, pMOONJAcolor, pBACKcolor, false, 0x0d0a, &box_width, &line_height);
      //----------------------------------------------------------------------------------------------------------------

      //[설명!!!]{------------------------------------------------------
      //출력 행의 범위를 계산한다.
      //여기서 "행" 은 "문서" 의 행을 말한다.(출력 영역의 행이 아니다.)
      //여기서 구한 두행 사이의 문서행만 실제로 출력하게 된다.
      //}---------------------------------------------------------------

      if(pY < 0)
      {
        //출력 시작 위치가 [음수] 인 경우, [음수 영역] 은 출력대상이 되지 않는다.

        //[출력 시작 행]
        doc_line_start = ((-1) * pY) / line_height;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
      else
      {
        //표시영역안은 항상 문서의 0 행부터 출력하면 된다.

        //[출력 시작 행]
        doc_line_start = 0;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - pY) / line_height;

      }
      
  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      //[앞선 무효영역 제거]
      //{
          //doc_line_start 보다 작은 행은 표시할 필요가 없으므로 CRLF 를 찾아서
          //doc_line_start 행의 첫 문자의 위치를 찾아서 여기서 부터 출력한다.

          for(i = pStartIndex, //지정 위치부터 문자열 출력을 시작한다.
              line_number = 0;
              //지정 위치까지 처리한다.
              (i < pEndIndex) && (pSTRING[i] != '\0') ;
             )
          {
            //처음행은 CRLF 전에 위치하므로 여기서 먼저 행을 검사한다.
            if(line_number == doc_line_start)
            {
              //출력으르 시작할 문서의 행을 얻었으므로 다음 처리로 들어간다.
              break;

            }

            if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
            {
              //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

              //다음 행의 좌표로 수정한다.
              pX  = 0;
              pY += line_height;

              i  += 2;

              //다음 행번호를 지정한다.
              line_number++;

            }
            else
            {
              i++;

            }

          }
      //}

      for(/*위에서 계속되는 값을 사용한다.*/;
          //지정 위치까지 처리한다.
          (i < pEndIndex) && (pSTRING[i] != '\0') ;
         )
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }
        else if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
        {
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //다음 행의 좌표로 수정한다.
          pX  = 0;
          pY += box_height;

          i += 2;

          //다음 행번호를 지정한다.
          line_number++;

          if(!(line_number <= doc_line_end))
          {
            //처리행을 넘었으므로 더이상 처리하지 않는다.
            goto END;

          }

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, pSTYLE, code,
                                  pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                                  &box_width, &box_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }

      }
  //}

  END:

  (*rX) = pX;
  (*rY) = pY;

  return(true);

}

bool __fastcall Font_StyleStr_AutoLine(//[문자] 를 출력할 bitmap handle.
                                       Graphics::TBitmap  *pViewHandle,
                                       //[사용 글꼴 묶음].
                                       struct FONTPACK    *pFontPack,
                                       //문자열을 출력할 시작 위치.(BASE:0)
                                       int                 pX,
                                       int                 pY,

                                       //[2012.05.15.화][추가!!!]{----------------------------------
                                       //[출력폭] 을 지정(0 인 경우 사용하지 않음).
                                       //이 [출력폭] 을 넘는 경우 CRLF 없이 자동으로 행을 바꿔준다.
                                       //<pViewHandle> (0, 0) 위치를 기준으로 한 폭이 된다.
                                       int                 pWidth,
                                       //}----------------------------------------------------------

                                       //문자색.
                                       int                 pMoonjaColor,
                                       //배경색.
                                       int                 pBackColor,
                                       //배경색투명속성지정.
                                       bool                pBackTransparent,
                                       //문자출력형식지정.(기본글꼴/굵은글꼴...)
                                       int                 pStyle,
                                       //출력할 문자열.
                                       char               *pStr,
                                       //[field option]--------------------------------
                                       //밑줄 종류.
                                       int                 pUnderLineKind,
                                       //[공백] 에도 적용할지여부.
                                       bool                pUnderLineSpace,
                                       //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                       int                 pUnderLineOffset,
                                       //밑줄 색.
                                       int                 pUnderLineColor,
                                       //----------------------------------------------
                                       //문자열 출력후 변경된 (x, y) 좌표를 반환한다.
                                       int                *rX,
                                       int                *rY)
{
  //[2012.05.15.화][생성!!!]{----------------------------------------------
  //<FONT_Out_StyleString2()> 함수를 사용한 것으로 [지정폭] 에 맞추어
  //자동으로 [행바꿈] 하는 기능을 가진다.
  //
  //[출력폭] 을 지정하여 문자열을 출력하는 경우 [자동 줄바꿈] 처리가
  //필요한 모든 곳에서 사용가능하다.
  //
  //이 함수는 [여러행] 의 경우도 완벽하게 [자동 줄바꿈] 이 모두 적용된다.
  //
  //[주의!!!]--------------------------------------------------------------
  //<CRLF> 를 끼워 넣는 것이 아니라 직접 행을 바꾸어 출력하는 것.
  //
  //이는 [색동문자] 를 적용하여 [풍선도움말] 이나 여러 곳에 출력하는경우
  //<CRLF> 를 넣는 경우 [색동문자] 가 적용된 단어가 깨지게 되어 더이상
  //적용단어가 아니게 되는 것을 방지하기 위한것이다.
  //이 함수 자체는 [색동문자] 가 적용되지 않지만 이 함수 자체도 필요하므로
  //새로 만든다.
  //
  //[참고!!!]--------------------------------------------------------------
  //<pWidth> 가 문자 한개 폭 보다 작은 경우라도 처리시 [행바꿈 뒤 출력]
  //으로 처리되므로 항상 행당 1문자는 출력되므로 오류가 발생하지 않는다.
  //더불어, <pViewHandle> 영역을 벗어나는 경우 더이상 출력되지 않으므로
  //굳이 <pWidth> 가 너무 작은 경우인지 판별할 필요는 없다.
  //
  //[중요!!!]--------------------------------------------------------------
  //<pWidth:0> 인 경우는 [일반출력] 으로 처리한다.
  //이 경우는 <FONT_Out_StyleString2()> 함수와 동일하다.
  //}----------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             boxWidth, boxHeight;

      //<2 Byte Code> 문자의 [문자값].
      unsigned short  code;

      int             i;

      //[출력행계산관련]
      //{
          //현재 출력하는 문서의 행번호.
          int         lineNumber = 0;

          //문자 출력 행의 높이.
          int         lineHeight;
          //출력 시작 행 번호(BASE:0)
          int         docLineStart;
          //출력 끝 행 번호(BASE:0)
          int         docLineEnd;
          
      //}
      
      //[2012.05.15.화][추가!!!]{----------------------------------------
      //[자동 줄바꿈] 처리시 <FONT_Out_StyleMoonja()> 함수로 미리 문자를
      //출력해 보지 않고도 쉽게 [지정폭] 을 벗어났는지 계산할때 필요.
      //이는 시간을 단축하기 위한것.
      int  korWidth; //한글 문자폭.
      int  engWidth; //영문 문자폭.
      //}----------------------------------------------------------------

  //}

  //[<한글/영문> 문자 폭 얻기]
  //{
      //[2012.05.15.화][추가!!!]{----------------------------------------------------
      //[지정폭] 을 넘었는지 계산하는 부분에서 사용되는 [문자폭] 을 미리 구해놓는다.
      //출력은 하지 않고 처리.
      //
      //이를 위하여 금일 <FONT_Out_Moonja()> 를 <pViewHandle:NULL> 인 경우
      //출력하지 않고 [문자:폭/높이] 정보만 반환하는 것으로 수정하였다.
      //}----------------------------------------------------------------------------

      //[한글 문자폭 얻기]
      //{
          code = ((((unsigned short)"김"[0]) << 8) & 0xff00) |
                 ((((unsigned short)"김"[1]) << 0) & 0x00ff);


          //FONT_Out_Moonja(pViewHandle, pFontPack, 0, 0, pMoonjaColor, pBackColor, false, code, &korWidth, NULL);
          //이미 만들어 놓은 보다 정확한 함수를 사용한다.
          FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &korWidth, NULL);

      //}

      //[영문 문자폭 얻기]
      //{
          code = "A"[0];

          //FONT_Out_Moonja(pViewHandle, pFontPack, 0, 0, pMoonjaColor, pBackColor, false, code, &engWidth, NULL);
          //이미 만들어 놓은 보다 정확한 함수를 사용한다.
          FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &engWidth, NULL);

      //}

  //}

  //[출력 행 정보 계산]
  //{
      //[행높이 구하기]{----------------------------------------------------------------------------------------------
      //[글꼴] 의 크기를 알기 위한 CRLF 문자 출력.
      FONT_Out_Moonja(pViewHandle, pFontPack, 0, 0, pMoonjaColor, pBackColor, false, 0x0d0a, &boxWidth, &lineHeight);
      //--------------------------------------------------------------------------------------------------------------

      //[설명!!!]{------------------------------------------------------------
      //출력 행의 범위를 계산한다.
      //여기서 "행" 은 "문서" 의 행을 말한다(출력 영역의 행이 아님).
      //여기서 구한 두행 사이의 문서행만 실제로 출력하게 된다.
      //
      //[2012.05.15.화][설명!!!]----------------------------------------------
      //이는 보이지 않는 영역인 경우 출력이 무의미 하므로 처리하지 않음으로써
      //처리 시간을 단축시키기 위한것.
      //}---------------------------------------------------------------------

      if(pY < 0)
      {
        //출력 시작 위치가 [음수] 인 경우, [음수 영역] 은 출력대상이 되지 않는다.

        //[출력 시작 행]
        docLineStart = ((-1) * pY) / lineHeight;

        //[출력 끝 행]
        docLineEnd   = (pViewHandle->Height - pY) / lineHeight;

      }
      else
      {
        //표시영역안은 항상 문서의 0 행부터 출력하면 된다.

        //[출력 시작 행]
        docLineStart = 0;

        //[출력 끝 행]
        docLineEnd   = (pViewHandle->Height - pY) / lineHeight;

      }

  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      //[앞선 무효영역 제거]
      //{
          //[!]{--------------------------------------------------------------
          //docLineStart 보다 작은 행은 표시할 필요가 없으므로 CRLF 를 찾아서
          //docLineStart 행의 첫 문자의 위치를 찾아서 여기서 부터 출력한다.
          //}-----------------------------------------------------------------

          for(i = 0, lineNumber = 0;
              //[문자열] 끝이 나올때 까지 처리한다.
              pStr[i] != '\0';
             )
          {
            //처음행은 CRLF 전에 위치하므로 여기서 먼저 행을 검사한다.
            if(lineNumber == docLineStart)
            {
              //출력으르 시작할 문서의 행을 얻었으므로 다음 처리로 들어간다.
              break;

            }

            if((pStr[i] == 0x0d) && (pStr[i+1] == 0x0a))
            {
              //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

              //다음 행의 좌표로 수정한다.
              pX  = 0;
              pY += lineHeight;

              i  += 2;

              //다음 행번호를 지정한다.
              lineNumber++;

            }
            else
            {
              i++;

            }

          }
      //}

      for(/*위에서 계속되는 값을 사용한다.*/;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pStr[i] != '\0';
         )
      {
        if     (pStr[i] == '\t')
        {
          //[자동 행바꿈 상황인가?]
          //{
              //[2012.05.15.화][추가!!!]{---------------------------------------------------------
              //현재 [문자] 를 출력할 경우 지정 폭을 넘어간다면 <CRLF> 처리와 동일한 처리를 한다.
              //}---------------------------------------------------------------------------------

              if(pWidth > 0)
              {
                //[!]{-----------------------------------------------------------
                //<pWidth:0> 인 경우는 [자동 행바꿈] 을 적용하지 않고 일반 출력.
                //}--------------------------------------------------------------

                if((pX + engWidth) > pWidth)
                {
                  //다음 행의 좌표로 수정한다.
                  pX  = 0;
                  pY += lineHeight;

                  //다음 행번호를 지정한다.
                  lineNumber++;

                }

              }

          //}

          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pViewHandle, pFontPack, pX, pY, pMoonjaColor, pBackColor, pBackTransparent, pStyle, code,
                                  pUnderLineKind, pUnderLineSpace, pUnderLineOffset, pUnderLineColor,
                                  &boxWidth, &boxHeight) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += boxWidth;

          i++;

        }
        else if((pStr[i] == 0x0d) && (pStr[i+1] == 0x0a))
        {
          //[!]{-------------------------------------------------------------------------
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.
          //}----------------------------------------------------------------------------

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Out_StyleMoonja(pViewHandle, pFontPack, pX, pY, pMoonjaColor, pBackColor, pBackTransparent, pStyle, code,
                                  pUnderLineKind, pUnderLineSpace, pUnderLineOffset, pUnderLineColor,
                                  &boxWidth, &boxHeight) != true)
          {
            return(false);
            
          }

          //다음 행의 좌표로 수정한다.
          pX  = 0;
          pY += boxHeight;

          i += 2;

          //다음 행번호를 지정한다.
          lineNumber++;

          if(!(lineNumber <= docLineEnd))
          {
            //처리행을 넘었으므로 더이상 처리하지 않는다.
            goto lbEnd;

          }

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 문자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pStr[i] < 0) && (pStr[i + 1] < 0))
        //else if(pStr[i] < 0)
        {
          //[!]{--------------------------
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.
          //}-----------------------------
          
          //[자동 행바꿈 상황인가?]
          //{
              //[2012.05.15.화][추가!!!]{---------------------------------------------------------
              //현재 [문자] 를 출력할 경우 지정 폭을 넘어간다면 <CRLF> 처리와 동일한 처리를 한다.
              //}---------------------------------------------------------------------------------

              if(pWidth > 0)
              {
                //[!]{-----------------------------------------------------------
                //<pWidth:0> 인 경우는 [자동 행바꿈] 을 적용하지 않고 일반 출력.
                //}--------------------------------------------------------------

                if((pX + korWidth) > pWidth)
                {
                  //다음 행의 좌표로 수정한다.
                  pX  = 0;
                  pY += lineHeight;

                  //다음 행번호를 지정한다.
                  lineNumber++;

                }

              }

          //}

          //2byte-code 합성.
          code = ((((unsigned short)pStr[i])   << 8) & 0xff00) |
                 ((((unsigned short)pStr[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pViewHandle, pFontPack, pX, pY, pMoonjaColor, pBackColor, pBackTransparent, pStyle, code,
                                  pUnderLineKind, pUnderLineSpace, pUnderLineOffset, pUnderLineColor,
                                  &boxWidth, &boxHeight) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += boxWidth;

          i += 2;

        }
        else
        {
          //[!]{----------------
          //1byte-code 인 경우.
          //[영문] 이 해당한다.
          //}-------------------

          //[자동 행바꿈 상황인가?]
          //{
              //[2012.05.15.화][추가!!!]{---------------------------------------------------------
              //현재 [문자] 를 출력할 경우 지정 폭을 넘어간다면 <CRLF> 처리와 동일한 처리를 한다.
              //}---------------------------------------------------------------------------------

              if(pWidth > 0)
              {
                //[!]{-----------------------------------------------------------
                //<pWidth:0> 인 경우는 [자동 행바꿈] 을 적용하지 않고 일반 출력.
                //}--------------------------------------------------------------

                if((pX + engWidth) > pWidth)
                {
                  //다음 행의 좌표로 수정한다.
                  pX  = 0;
                  pY += lineHeight;

                  //다음 행번호를 지정한다.
                  lineNumber++;

                }

              }

          //}

          code = pStr[i];

          //[문자] 출력.
          if(FONT_Out_StyleMoonja(pViewHandle, pFontPack, pX, pY, pMoonjaColor, pBackColor, pBackTransparent, pStyle, code,
                                  pUnderLineKind, pUnderLineSpace, pUnderLineOffset, pUnderLineColor,
                                  &boxWidth, &boxHeight) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += boxWidth;

          i++;

        }

      }
  //}

  lbEnd:

  if(rX != NULL) { (*rX) = pX; }
  if(rY != NULL) { (*rY) = pY; }

  return(true);

}

bool __fastcall FONT_Out_String2_withLINEstartINDEX(//[문자] 를 출력할 bitmap handle.
                                                    Graphics::TBitmap  *pVIEWhandle,
                                                    //[사용 글꼴 묶음].
                                                    struct FONTPACK    *pFONTPACK,
                                                    //문자열을 출력할 시작 위치.(BASE:0)
                                                    int                 pX,
                                                    int                 pY,
                                                    //문자색.
                                                    int                 pMOONJAcolor,
                                                    //배경색.
                                                    int                 pBACKcolor,
                                                    //배경색투명속성지정.
                                                    bool                pBACKtransparent,
                                                    //출력할 문자열.
                                                    char               *pSTRING,
                                                    //출력할 시작 index.(pSTRING[pLINEstartINDEX] 로 사용된다.)
                                                    int                 pLINEstartINDEX,
                                                    //행높이.
                                                    int                 pLINEheight,
                                                    //[field option]--------------------------------
                                                    //밑줄 종류.
                                                    int                 pUNDERLINEkind,
                                                    //[공백] 에도 적용할지여부.
                                                    bool                pUNDERLINEspace,
                                                    //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                                    int                 pUNDERLINEoffset,
                                                    //밑줄 색.
                                                    int                 pUNDERLINEcolor)
{
  //[2006.12.30.토][생성!!!]{------------------------------------------------------------------------
  //FONT_Out_String2() 함수를 그대로 사용하고 pLINEstartINDEX 를 지정하여 출력할수 있도록
  //수정한 것이다.
  //FONT_Out_String2() 함수는 계속 행을 계산하는데, 문서량이 많은 경우는 시간을 많이 손실하게 되므로
  //이미 계산되 있는 지정 index 부터 문자열을 출력하는 것으로 내용을 추가 수정한 것이다.
  //}------------------------------------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             box_width, box_height;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //[출력행계산관련]
      //{
          //현재 출력하는 문서의 행번호.
          int         line_number = 0;

          //출력 시작 행 번호(BASE:0)
          int         doc_line_start;
          //출력 끝 행 번호(BASE:0)
          int         doc_line_end;
      //}
  //}

  //[출력 행 정보 계산]
  //{

      //[설명!!!]{------------------------------------------------------
      //출력 행의 범위를 계산한다.
      //여기서 "행" 은 "문서" 의 행을 말한다.(출력 영역의 행이 아니다.)
      //여기서 구한 두행 사이의 문서행만 실제로 출력하게 된다.
      //}---------------------------------------------------------------

      //[보정]
      //{
          //[문서원점] 은 +2 의 offset 이 존재하므로 -2 해서 원래 값으로 돌려놓고
          //행을 계산해야 바른 값을 얻을수 있다.
      //}

      if(pY < 0)
      {
        //출력 시작 위치가 [음수] 인 경우, [음수 영역] 은 출력대상이 되지 않는다.

        //[출력 시작 행]
        doc_line_start = ((-1) * (pY - 2)) / pLINEheight;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - (pY - 2)) / pLINEheight;

      }
      else
      {
        //표시영역안은 항상 문서의 0 행부터 출력하면 된다.

        //[출력 시작 행]
        doc_line_start = 0;

        //[출력 끝 행]
        doc_line_end   = (pVIEWhandle->Height - (pY - 2)) / pLINEheight;

      }
  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      //[출력위치계산]
      //{
          //------------------------------------
          //pX = 0 이되므로 pY 만 계산한다.
          pY += (doc_line_start * pLINEheight);
          line_number = doc_line_start;
          //------------------------------------
      //}

      for(i = pLINEstartINDEX;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pSTRING[i] != '\0';
         )
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }
        else if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
        {
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 pY 위치만 수정한다.

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //다음 행의 좌표로 수정한다.
          pX  = 0;
          pY += box_height;

          i += 2;

          //다음 행번호를 지정한다.
          line_number++;

          if(!(line_number <= doc_line_end))
          {
            //처리행을 넘었으므로 더이상 처리하지 않는다.
            return(true);

          }

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }

      }
  //}

  return(true);

}

bool __fastcall FONT_Out_LineStr_withSTARTENDindex(//[문자] 를 출력할 bitmap handle.
                                                   Graphics::TBitmap  *pVIEWhandle,
                                                   //[사용 글꼴 묶음].
                                                   struct FONTPACK    *pFONTPACK,
                                                   //문자열을 출력할 시작 위치.(BASE:0)
                                                   int                 pX,
                                                   int                 pY,
                                                   //문자색.
                                                   int                 pMOONJAcolor,
                                                   //배경색.
                                                   int                 pBACKcolor,
                                                   //배경색투명속성지정.
                                                   bool                pBACKtransparent,
                                                   //출력할 문자열.
                                                   char               *pSTRING,
                                                   //출력할 시작 index.
                                                   int                 pSTARTindex,
                                                   //출력할 끝 index.
                                                   int                 pENDindex,
                                                   //[field option]--------------------------------
                                                   //밑줄 종류.
                                                   int                 pUNDERLINEkind,
                                                   //[공백] 에도 적용할지여부.
                                                   bool                pUNDERLINEspace,
                                                   //문자 출력 BOX 영역의 아래를 기준으로 한 위치.
                                                   int                 pUNDERLINEoffset,
                                                   //밑줄 색.
                                                   int                 pUNDERLINEcolor)
{
  //[2007.01.13.토][생성!!!]{--------------------------------------------------------------------
  //한행에서만 유효하고 버퍼상에서 startindex 와 endindex 로 지정된 부분을 지정 위치에 출력한다.
  //이는 [편집기] 상에서 [입력지정자] 의 위치에 문자를 출력하는 경우 사용된다.
  //한 행만을 대상으로 하므로 CRLF 는 처리하지 않고 단지 '\t' 만 구분하여 처리한다.
  //}--------------------------------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             box_width, box_height;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;
  //}

  //[문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      for(i = pSTARTindex; i <= pENDindex;)
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Out_Moonja2(pVIEWhandle, pFONTPACK, pX, pY, pMOONJAcolor, pBACKcolor, pBACKtransparent, code,
                              pUNDERLINEkind, pUNDERLINEspace, pUNDERLINEoffset, pUNDERLINEcolor,
                              &box_width, &box_height) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          pX += box_width;

          i++;

        }

      }
  //}

  END:

  return(true);

}

bool __fastcall FONT_Get_MoonjaOutAreaInfo(//[사용 글꼴 묶음].
                                           struct FONTPACK    *pFONTPACK,
                                           //[2010.01.30.토][추가!!!]
                                           //[보통글꼴/굵은글꼴] 을 구분한다.
                                           int                 pStyle,
                                           //출력 문자 코드.
                                           unsigned short      pCODE,
                                           //출력된 문자 width, height 정보 반환.
                                           //[2012.05.15.화][수정!!!]
                                           //NULL 인 경우는 반환하지 않는다.
                                           int                *rWIDTH,
                                           int                *rHEIGHT)
{
  //[2006.11.07.화][생성!!!]{---------------------------------------------
  //pCODE 에 해당하는 [문자] 의 출력시 문자영역의 [폭], [높이] 를 구한다.
  //실제 출력하지는 않고 가상 출력하여 영역의 크기만 알아낸다.
  //
  //[2012.05.15.화][수정!!!]----------------------------------------------
  //}---------------------------------------------------------------------

  //[VAR]
  //{
      //사용할 [글꼴].
      unsigned char        *font;
      int                   font_index;

      //*.gft 파일의 header handle 을 얻는다.
      unsigned int         *header;

      //출력할 [문자] 의 [순번].
      int                   moonja_order;

      //글꼴 정보.
      int                   height;
      unsigned int          option;
      int                   DW;

      //[기본:가변 글꼴] 의 경우 DW-table 에 접근하기 위한 handle.
      //DW-table 은 각각 2byte 로 구성되 있다.
      unsigned short       *DW_table;

      //[문자열 글꼴] 의 경우 [문자 헤더 테이블] handle 을 가진다.
      unsigned long long   *moonja_header_handle;
      unsigned long long    moonja_header;

      //실제 margin 이 적용된 문자 출력 영역.
      int                   box_width, box_height;

      //[2010.01.25.월][추가!!!]{-------------------------------------------------------
      //<FONT_Get_MoonjaPtr_byCODE()> 함수를 위하여 추가한다.
      //이 함수가 있어야 <moonja_order> 를 알수 있는데, 이제껏 이를 사용하지 않아서
      //[가변글꼴] 인 경우 <moonja_order> 이 정보를 알수 없어서 계속 오류가 발생하였다.
      //금일 [그림부품] 을 새로 만들면서 [글꼴] 적용시 이 문제를 발견하고 수정한다.
      //실제 이 변수안의 값을 사용하지는 않는다.
      int  index_byte, index_bit;
      //}-------------------------------------------------------------------------------

  //}

  //[CRLF 처리]
  //{
      //-----------------------------------------------------------------------------------------
      //출력 code 가 CRLF 인 경우는 [문자] 가 없는 것이므로 일단 [공백] 으로 대체한다.
      //단지 정보를 얻기 위한 것으로 이 함수 중간의 해당 처리부에서 정보를 얻기 위하여 필요하다.
      //이 [문자] 는 실제 출력되지는 않으며, 각각의 해당 처리 함수에서 해당 하지 않는 code 로
      //인하여 return(fasle)  로 처리되는 것을 막기 위한 것이다.
      if(pCODE == 0x0d0a)
      {
        pCODE   = ' ';

      }
      //-----------------------------------------------------------------------------------------
  //}

  //[글꼴 handle 얻기]
  //{
      //[2010.01.25.월][중요수정!!!]{--------------------------------------------------
      //[가변글꼴] 인 경우 <moonja_order> 정보를 구하는 것이 없어서 [가변글꼴] 의 경우
      //계속 오류가 발생하였다. 이를 금일 새로운 [그림부품] 의 여러 글꼴을 적용하는
      //과정에서 발견하고 이를 수정한다.
      //}------------------------------------------------------------------------------

      //[수정안]
      //{
          //[!]{-----------------------------------------------------------------------------
          //[가변글꼴] 인 경우는 <moonja_order> 정보가 반드시 필요하므로 이 정보를 알수 있는
          //<FONT_Get_MoonjaPtr_byCODE> 함수를 사용하는 것으로 수정한다.
          //}---------------------------------------------------------------------------------

          if(FONT_Get_MoonjaPtr_byCODE(pFONTPACK, pCODE, &font_index, &moonja_order, &index_byte, &index_bit) != true)
          {
            //없는 코드 문자로 대체한다.
            pCODE = 0xa2c6; //▒ 문자가 해당한다.

          }

      //}

      //[이전안]
      //{
          //이 함수는 <moonja_order> 정보를 얻을수 없으므로 위의 함수를 사용하는 것으로 수정한다.

          /*
          //pCODE 를 가진 [글꼴] 의 handle 을 얻는다.
          if(FONT_Get_FontHandle_byCODE(pFONTPACK, pCODE, &font_index) != true)
          {
            return(false);

          }
          */

      //}

  //}

  //[글꼴 출력 형식 구분]
  //{
      //[2010.01.30.토][중요수정!!!]{-------------------------------------------------
      //[굵은글꼴] 의 경우 [보통글꼴] 과 전혀 다른 글꼴일수 있으므로 이 경우를 따져서
      //해당 글꼴에 맞는 정확한 정보를 얻을수 있게 수정한다.
      //}-----------------------------------------------------------------------------

      //출력 형식에 따른 해당 글꼴의 관리주소값을 얻는다.

      switch(pStyle)
      {
        case d_FONTSTYLE_default :
        {
          //[기본형식 출력]

          //기본값을 그대로 사용하면 된다.
          font = pFONTPACK->gft[font_index];

        } break;

        case d_FONTSTYLE_bold :
        {
          //[굵은글꼴 출력]

          //현재 + 4 의 index 위치가 이 글꼴의 [굵은글꼴] 이 된다.
          font = pFONTPACK->gft[font_index + d_FONTSTYLE_bold] ;

        } break;

      }

  //}

  //[글꼴정보]
  //{
      //---------------------------------------------------------------------------------------
      //모든 *.gft 파일의 정보는 Big-Endian 으로 되 있으므로 Little-Endian 으로 변환해야 한다.

      //header-handle 구하기.(글꼴의 처음 시작 위치와 같다.)
      header   = (unsigned int *)font;

      //가로, 세로 크기를 구한다.
      height   = ENDIAN_BigToLittle_4(header[d_HEADER_height_ix]);
      option   = ENDIAN_BigToLittle_4(header[d_HEADER_language_ix]);
      //---------------------------------------------------------------------------------------
  //}

  //[DW 값 구하기]
  //{
      //[설명]{----------------------------------------------------------------
      //출력폭을 결정하는 DW 값을 얻는다.
      //[기본 글꼴]
      //=>[고정폭] : [글꼴 헤더] 의 DW 값을 바로 사용하면 된다.
      //=>[가변폭] : [DW-table] 의 해당 문자 order 의 DW 값을 사용한다.
      //
      //[문자열 글꼴]
      //[문자열 글꼴] 은 [고정/가변폭] 에 상관없이 각각의 [문자헤더] 안에 모든
      //정보가 있므으로 각각의 [문자헤더] 안의 DW 값을 사용한다.
      //}----------------------------------------------------------------------

      switch((option >> d_LANGUAGE_default_string_bt) & 0x00000001)
      {
        case d_default_bv : //[기본 글꼴]
        {
          //[고정/가변 글꼴] 에 따라서 DW 정보 위치가 달라지므로 구분하여 처리한다.
          switch((option >> d_LANGUAGE_fixed_variable_bt) & 0x00000001)
          {
            case d_fixed_bv    : //[고정폭 글꼴]
            {
              //[고정폭] 인 경우는 [글꼴 헤더] 안의 DW 기본 값을 사용하면된다.
              DW = ENDIAN_BigToLittle_4(header[d_HEADER_DWinfo_ix]);

            } break;

            case d_variable_bv : //[가변폭 글꼴]
            {
              //[가변폭] 인 경우는 DW-table(2byte 단위) 에서 지금 문자의 DW 값을 추출한다.
              //Big-Endian 으로 되 있으므로 변환처리한다.

              //DW-table 의 handle 을 얻는다.
              DW_table = (unsigned short *)(&(((unsigned int *)font)[d_HEADER_table_ix]));

              //현 문자의 DW 값을 얻는다.
              DW = ENDIAN_BigToLittle_2(DW_table[moonja_order]);

            } break;

          }

        } break;

        case d_string_bv  : //[문자열 글꼴]
        {
          //[문자 헤더 구조][64bit]{---------------------------
          //{   DW   } + {byte 위치} + {bit 위치} + {  code  }
          // .[63:51]     .[50:19]      .[18:16]     .[15:0]
          //   13bit        32bit         3bit         16bit
          //  x : byte 크기.
          // .x : bit 번호.
          //}--------------------------------------------------

          //해당 문자의 [문자 헤더] 의 DW 값을 추출한다.

          //[문자열 글꼴] 의 [문자 헤더 테이블] 위치를 얻는다.
          moonja_header_handle = (unsigned long long *)(&(header[d_HEADER_table_ix]));

          //문자의 [문자 헤더] 정보를 구한다.
          moonja_header = ENDIAN_BigToLittle_8(moonja_header_handle[moonja_order]);

          //DW 값을 구한다. ([문자열 글꼴] 에서는 13bit 크기를 갖는다.)
          DW = (moonja_header >> 51) & 0x1fff;

        } break;

      }
      
  //}

  //[출력 영역 정보][이전안!!!]
  //{
      //[2010.01.25.월][주석처리!!!]
      /*
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;
      box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;
      */
  //}

  //[출력 영역 정보]
  //{
      //[!]{------------------------------------------
      //실제 [문자] 가 출력되는 영역의 크기를 구한다.
      //}---------------------------------------------

      //[문자 출력 폭 계산]
      //{
          //[2010.01.25.월][중요수정!!!]{-----------------------------------------------
          //[영문] 의 경우는 미리 지정한 전용 [왼쪽/오른쪽 여백] 을 추가해 주어야 한다.
          //[영문글꼴] [글꼴묶음] 의 index[3, 7] 에 해당한다.
          //}---------------------------------------------------------------------------

          if((font_index == 3) || (font_index == 7))
          {
            //[영문글꼴] 인 경우.

            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right +
                         pFONTPACK->en_offset_left + pFONTPACK->en_offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

          }
          else
          {
            box_width  = DW     + pFONTPACK->offset_left + pFONTPACK->offset_right;

            box_height = height + pFONTPACK->offset_top  + pFONTPACK->offset_bottom;

          }

      //}

  //}

  //[반환]
  //{
      //[!]{----------------------------
      //[문자] 출력 영역 정보 반환.
      //
      //[2012.05.15.화][수정!!!]--------
      //NULL 인 경우는 반환하지 않는다.
      //}-------------------------------

      if(rWIDTH  != NULL) { (*rWIDTH)  = box_width;  }
      if(rHEIGHT != NULL) { (*rHEIGHT) = box_height; }
      
  //}

  return(true);

}

bool __fastcall FONT_Get_StringOutAreaInfo(//[사용 글꼴 묶음].
                                           struct FONTPACK  *pFONTPACK,
                                           //[2010.01.30.토][추가!!!]
                                           //[보통글꼴/굵은글꼴] 을 구분한다.
                                           int               pStyle,
                                           //출력할 문자열.
                                           char             *pSTRING,
                                           //문자열이 출력 영역 크기 정보.
                                           int              *rWIDTH,
                                           int              *rHEIGHT)
{
  //[2006.11.07.화][생성!!!]{--------------------------------------------------
  //문자열을 직접 출력하지는 않고 가상적으로 출력하여 문자열의 출력시 차지하는
  //출력 영역의 [폭], [높이] 값을 구한다.
  //x = 0, y = 0, margin = 0 으로 기본값을 사용하지만, 글꼴 자체의
  //offset 정보는 실제 문자의 높이 넓이에 관련되므로 이 값은 그대로 사용한다.
  //}--------------------------------------------------------------------------

  //[주의!!!]
  //{
      //------------------------------------------------------------------------
      //1) 가상적인 출력이므로 모든 문서를 다 출력하는 것으로 보고 처리한다.
      //2) 영역의 폭은 가장 큰 것을 문자열 출력 영역의 [폭] 으로 본다.
      //3) 전달받은 문자열이 한 행으로 된 경우는 별도 처리를 해주어야 한다.
      //4) 문자열이 있는한 무조건 1 행은 있는 것으로 보아야 하므로 1행의 높이를
      //   더해서 반환한다.
      //------------------------------------------------------------------------
  //}

  //[VAR]
  //{
      //출력한 [문자] 의 영역 크기.
      int             moonja_widh   = 0,
                      moonja_height = 0;

      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      int             width  = 0;
      int             height = 0;

      //가장 큰 [폭] 값을 기록한다.(이 값이 반환할 width 값이 된다.)
      int             max_width = 0;
  //}

  //[가상 문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      for(i = 0;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pSTRING[i] != '\0';
         )
      {
        if     (pSTRING[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';
                                                         
          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFONTPACK, pStyle, code, &moonja_widh, &moonja_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          width += moonja_widh;

          i++;

        }
        else if((pSTRING[i] == 0x0d) && (pSTRING[i+1] == 0x0a))
        {
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 height 위치만 수정한다.

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Get_MoonjaOutAreaInfo(pFONTPACK, pStyle, code, &moonja_widh, &moonja_height) != true)
          {
            return(false);

          }

          //[최대폭 검사]
          //{
              //-------------------------------------------------------------
              //이 행의 width 값이 현재까지 최대 값인지 검사한다.
              if(max_width < width)
              {
                //현재 값이 최대 값이라면 이 값을 다시 최대 값으로 저장한다.
                max_width = width;

              }
              //-------------------------------------------------------------
          //}

          //다음 행의 좌표로 수정한다.
          width   = 0;
          height += moonja_height;

          i += 2;

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 무자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pSTRING[i] < 0) && (pSTRING[i + 1] < 0))
        //else if(pSTRING[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pSTRING[i])   << 8) & 0xff00) |
                 ((((unsigned short)pSTRING[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFONTPACK, pStyle, code, &moonja_widh, &moonja_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          width += moonja_widh;

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pSTRING[i];

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFONTPACK, pStyle, code, &moonja_widh, &moonja_height) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          width += moonja_widh;

          i++;

        }

      }
  //}

  //[최대폭 검사]
  //{
      //마지막행이 CRLF 로 끝나지 않는 경우도 처리 되어야 하므로 한번더 처리한다.
      //이 행의 width 값이 현재까지 최대 값인지 검사한다.
      if(max_width < width)
      {
        //현재 값이 최대 값이라면 이 값을 다시 최대 값으로 저장한다.
        max_width = width;

      }
  //}

  //[영역 정보 반환]
  //{
      //[2012.05.28.월][수정!!!]{---
      //NULL 이 아닌 경우만 반환.
      //}---------------------------

      if(rWIDTH != NULL)  { (*rWIDTH)  = max_width;              }
      //행의경우는 마지막에 CRLF 로 끝나지 않을수도 있으므로 행 한개의 높이를 더해준다.
      if(rHEIGHT != NULL) { (*rHEIGHT) = height + moonja_height; }
      
  //}

  return(true);

}

int __fastcall FONT_Get_StringOutAreaInfo_Width(//[사용 글꼴 묶음].
                                                struct FONTPACK  *pFontPack,
                                                //[보통글꼴/굵은글꼴] 을 구분한다.
                                                int               pStyle,
                                                //출력할 문자열.
                                                char             *pStr)
{
  //[2011.07.16.토][생성!!!]{-------------------------------------------------------------
  //<FONT_Get_StringOutAreaInfo()> 함수를 사용하여 문자열의 출력 [폭] 을 구해서 반환한다.
  //}-------------------------------------------------------------------------------------

  //[VAR]
  //{
      int  strWidth;
      int  strHeight;

  //}

  //[검사]
  //{
      if((pFontPack == NULL) || (pStr == NULL)) return(-1);

  //}

  //[문자열 출력 정보 얻기]
  //{
      //처리시 오류가 발생한 경우는 <-1> 을 반환한다.
      if(FONT_Get_StringOutAreaInfo(pFontPack, pStyle, pStr, &strWidth, &strHeight) != true) return(-1);

  //}

  //[반환]
  //{
      return(strWidth);

  //}

}

bool __fastcall Font_LineStr_Get_Length_condWidth(//처리할 문자열.
                                                  char             *pStr,
                                                  //적용할 [글꼴 묶음].
                                                  struct FONTPACK  *pFontPack,
                                                  //[보통글꼴/굵은글꼴] 을 구분한다.
                                                  int               pStyle,
                                                  //지정 출력 영역 폭.
                                                  int               pSetWidth,
                                                  //지정 영역을 만족시키는 문자열 길이(NULL 이 아닌 경우만 반환).
                                                  int              *rStrLength)
{
  //[2011.06.28.화][생성!!!]{----------------------------------------------------------------
  //1행 문자열을 직접 출력하지는 않고 가상적으로 출력하여 지정된 폭에 [작거나 같은]
  //[문자열길이] 를 찾아서 반환한다.
  //
  //x = 0, y = 0, margin = 0 으로 기본값을 사용하지만, 글꼴 자체의
  //offset 정보는 실제 문자의 높이 넓이에 관련되므로 이 값은 그대로 사용한다.
  //
  //이 함수는 [제한된 폭] 에 출력되는 문자열을 잘라내서 맞추려는 경우를 위한 것이다.
  //
  //[참고!!!]--------------------------------------------------------------------------------
  //이 함수는 [한글] 이 절대 쪼개지지 않는다.
  //
  //[주의!!!]--------------------------------------------------------------------------------
  //이 함수는 반드시 <CRLF> 가 존재하지 않는 1행 문자열을 사용해야 한다.
  //
  //[2012.03.30.금][중요수정!!!]-------------------------------------------------------------
  //[지정폭] 를 넘는 경우 이전 <i> 위치가 반환되어야 하는데 이미 수정된 <i> 위치가
  //반환되어 한개 문자 단위 오차가 있었다.
  //즉, 문자 [한글/영문] 한개 단위로 [지정폭] 을 넘는 경우가 발생하였는데
  //금일 [풍선도움말(GBalloonBox.cpp)] 에 [자동줄바꿈] 기능 <_BalloonBoxAutoLineInPart()> 를
  //만들면서 발견하고 수정한다.
  //}----------------------------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 폭.
      int             mWidth = 0;

      //출력한 [문자] 의 높이.
      int             mHeight = 0;


      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //출력된 전체 폭.
      int             totalWidth  = 0;

  //}

  //[가상 문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      for(i = 0;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pStr[i] != '\0';
         )
      {
        if     (pStr[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &mWidth, &mHeight) != true) return(false);

          i++;

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 문자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pStr[i] < 0) && (pStr[i + 1] < 0))
        //else if(pStr[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pStr[i])   << 8) & 0xff00) |
                 ((((unsigned short)pStr[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &mWidth, &mHeight) != true) return(false);

          //[설정 폭과 비교]
          //{
              //[!]{-----------------------------------------------------------------
              //[지정 폭] 과 [출력 폭] 의 크기를 비교한다.
              //
              //[2012.03.30.금][수정!!!]---------------------------------------------
              //원래 [조건문] 마지막에서 검사하던 것을 <i> 가 수정되기 전
              //이 위치로 수정한다.
              //이는 아래 조건으로 종료하는 경우 수정전 <i> 값이 구하는 값이기 때문.
              //}--------------------------------------------------------------------

              //[이전출력폭 + 현재 문자 폭] 이 지정 폭보다 큰 경우는
              //이전 크기가 구하는 크기가 된다.
              if((totalWidth + mWidth) > pSetWidth)
              {
               //여기서 종료한다.
               //아직 <totalWidth> 를 수정하지 않았으므로 지금 값이 적용된다.
               break;

              }

          //}

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pStr[i];

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &mWidth, &mHeight) != true) return(false);

          //[설정 폭과 비교]
          //{
              //[!]{-----------------------------------------------------------------
              //[지정 폭] 과 [출력 폭] 의 크기를 비교한다.
              //
              //[2012.03.30.금][수정!!!]---------------------------------------------
              //원래 [조건문] 마지막에서 검사하던 것을 <i> 가 수정되기 전
              //이 위치로 수정한다.
              //이는 아래 조건으로 종료하는 경우 수정전 <i> 값이 구하는 값이기 때문.
              //}--------------------------------------------------------------------

              //[이전출력폭 + 현재 문자 폭] 이 지정 폭보다 큰 경우는
              //이전 크기가 구하는 크기가 된다.
              if((totalWidth + mWidth) > pSetWidth)
              {
               //여기서 종료한다.
               //아직 <totalWidth> 를 수정하지 않았으므로 지금 값이 적용된다.
               break;

              }

          //}

          i++;

        }

        //[문자] 출력 좌표 수정.
        totalWidth += mWidth;

      }

      //[!]{------------------------------------------------------------------------
      //여기까지 온 것은 [지정문자열] 을 모두 출력해도 [지정폭] 에 미달하는 것이다.
      //}---------------------------------------------------------------------------

  //}

  //[반환]
  //{
      //조정된 문자열 길이를 반환한다.
      if(rStrLength != NULL) { (*rStrLength) = i; }

  //}
  
  return(true);

}

/*
bool __fastcall Font_LineStr_Get_Length_condWidth(//처리할 문자열.
                                                  char             *pStr,
                                                  //적용할 [글꼴 묶음].
                                                  struct FONTPACK  *pFontPack,
                                                  //[보통글꼴/굵은글꼴] 을 구분한다.
                                                  int               pStyle,
                                                  //지정 출력 영역 폭.
                                                  int               pSetWidth,
                                                  //지정 영역을 만족시키는 문자열 길이(NULL 이 아닌 경우만 반환).
                                                  int              *rStrLength)
{
  //[2011.06.28.화][생성!!!]{--------------------------------------------------------
  //1행 문자열을 직접 출력하지는 않고 가상적으로 출력하여 지정된 폭에 [작거나 같은]
  //[문자열길이] 를 찾아서 반환한다.
  //단, [한글] 이 쪼개지지 않도록 <STR_SetLength()> 함수를 사용하여 최종적으로 다시
  //한번 조정한 값을 반환한다.
  //
  //x = 0, y = 0, margin = 0 으로 기본값을 사용하지만, 글꼴 자체의
  //offset 정보는 실제 문자의 높이 넓이에 관련되므로 이 값은 그대로 사용한다.
  //
  //이 함수는 [제한된 폭] 에 출력되는 문자열을 잘라내서 맞추려는 경우를 위한 것이다.
  //
  //[주의!!!]------------------------------------------------------------------------
  //이 함수는 반드시 <CRLF> 가 존재하지 않는 1행 문자열을 사용해야 한다.
  //}--------------------------------------------------------------------------------

  //[VAR]
  //{
      //출력한 [문자] 의 폭.
      int             mWidth = 0;

      //출력한 [문자] 의 높이.
      int             mHeight = 0;


      //2byte-code 문자의 code.
      unsigned short  code;

      int             i;

      //출력된 전체 폭.
      int             totalWidth  = 0;

  //}

  //[가상 문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      for(i = 0;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pStr[i] != '\0';
         )
      {
        if     (pStr[i] == '\t')
        {
          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &mWidth, &mHeight) != true) return(false);

          i++;

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 문자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pStr[i] < 0) && (pStr[i + 1] < 0))
        //else if(pStr[i] < 0)
        {
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.

          //2byte-code 합성.
          code = ((((unsigned short)pStr[i])   << 8) & 0xff00) |
                 ((((unsigned short)pStr[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &mWidth, &mHeight) != true) return(false);

          i += 2;

        }
        else
        {
          //1byte-code 인 경우.
          //[영문] 이 해당한다.

          code = pStr[i];

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &mWidth, &mHeight) != true) return(false);

          i++;

        }

        //[설정 폭과 비교]
        //{
            //[!]{---------------------------------------
            //[지정 폭] 과 [출력 폭] 의 크기를 비교한다.
            //}------------------------------------------

            //[이전출력폭 + 현재 문자 폭] 이 지정 폭보다 큰 경우는
            //이전 크기가 구하는 크기가 된다.
            if((totalWidth + mWidth) > pSetWidth)
            {
              //여기서 종료한다.
              //아직 <totalWidth> 를 수정하지 않았으므로 지금 값이 적용된다.
              break;

            }

        //}

        //[문자] 출력 좌표 수정.
        totalWidth += mWidth;

      }

      //[!]{------------------------------------------------------------------------
      //여기까지 온 것은 [지정문자열] 을 모두 출력해도 [지정폭] 에 미달하는 것이다.
      //}---------------------------------------------------------------------------

  //}

  //[반환]
  //{
      //조정된 문자열 길이를 반환한다.
      if(rStrLength != NULL) { (*rStrLength) = i; }

  //}
  
  return(true);

}
*/

bool __fastcall Font_Get_AutoLineStr_OutAreaInfo(//[사용 글꼴 묶음].
                                                 struct FONTPACK  *pFontPack,
                                                 //[2010.01.30.토][추가!!!]
                                                 //[보통글꼴/굵은글꼴] 을 구분한다.
                                                 int               pStyle,
                                                 //지정폭(이 폭을 넘는 경우 자동 줄바꿈).
                                                 int               pWidth,
                                                 //출력할 문자열.
                                                 char             *pStr,
                                                 //문자열이 출력 영역 크기 정보.
                                                 //[2012.05.16.수][수정!!!]{------------------------------
                                                 //<pWidth > 0> 이라도 정확한 실제 출력 [최대폭] 을 반환.
                                                 int              *rWidth,
                                                 //}------------------------------------------------------
                                                 int              *rHeight)
{
  //[2012.05.15.화][생성!!!]{------------------------------------------------------------------------
  //<FONT_Get_StringOutAreaInfo()> 를 사용하여 만든다.
  //
  //문자열을 직접 출력하지는 않고 가상적으로 출력하여 [지정폭:자동 줄바꿈] 의 경우를 반영하여
  //출력 영역의 [높이] 를 구한다.
  //
  //x = 0, y = 0, margin = 0 으로 기본값을 사용하지만, 글꼴 자체의 <offset> 정보는 실제
  //문자의 높이 넓이에 관련되므로 이 값은 그대로 사용.
  //
  //이 함수는 금일 <Font_StyleStr_AutoLine()> 함수를 만든후 같은 계통의 함수로 필요성이 있어 만든다.
  //
  //[주의!!!]{---------------------------------------------------------------------------------------
  //1) 가상적인 출력이므로 모든 문서를 다 출력하는 것으로 보고 처리.
  //2) 전달받은 문자열이 한 행으로 된 경우는 별도 처리를 해주어야 한다.
  //3) 문자열이 있는한 무조건 1 행은 있는 것으로 보아야 하므로 1행의 높이를
  //   더해서 반환한다.
  //
  //이 함수는 지정된 [폭] 안에서 [자동 줄바꿈] 되므로 [높이] 만 구하면 된다.
  //
  //[2012.05.16.수][수정!!!]-------------------------------------------------------------------------
  //(pWidth > 0) 인 경우라도  <rWidth> 는 정확한 [최대폭] 을 가지도록 계산된다.
  //이는 [문자열] 이 출력폭이 <pWidth> 를 넘지 않는 경우는 <pWidth> 가 반드시
  //[최대폭] 이라는 보장이 없기 때문이다.
  //즉, 실제 출력되는 [최대폭] 은 항상 <rWidth> 값이 정확한 값이다.
  //}------------------------------------------------------------------------------------------------
  
  //[VAR]
  //{
      //출력한 [문자] 영역 크기.
      int             moonjaWidh   = 0,
                      moonjaHeight = 0;

      //<2 Byte-code> 문자의 <code>.
      unsigned short  code;

      int             i;

      int             width  = 0;
      int             height = 0;
      
      //[!]{------------------------------------------------------------
      //<pWidth:0> 으로 [자동 줄바꿈] 이 적용되지 않을때만 의미가 있다.
      //어떤 경우라도 기본적으로 계속 값을 구해 놓는다.
      int             maxWidth = 0;
      //}---------------------------------------------------------------

      //[2012.05.15.화][추가!!!]{----------------------------------------
      //[자동 줄바꿈] 처리시 <FONT_Out_StyleMoonja()> 함수로 미리 문자를
      //출력해 보지 않고도 쉽게 [지정폭] 을 벗어났는지 계산할때 필요.
      //이는 시간을 단축하기 위한것.
      int  korWidth;   //한글 문자폭.
      int  engWidth;   //영문 문자폭.
      int  lineHeight; //행 높이.
      //}----------------------------------------------------------------

  //}

  //[<한글/영문> 문자 폭 얻기]
  //{
      //[2012.05.15.화][추가!!!]{----------------------------------------------------
      //[지정폭] 을 넘었는지 계산하는 부분에서 사용되는 [문자폭] 을 미리 구해놓는다.
      //출력은 하지 않고 처리.
      //
      //이를 위하여 금일 <FONT_Out_Moonja()> 를 <pViewHandle:NULL> 인 경우
      //출력하지 않고 [문자:폭/높이] 정보만 반환하는 것으로 수정하였다.
      //}----------------------------------------------------------------------------

      //[한글 문자폭 얻기]
      //{
          code = ((((unsigned short)"김"[0]) << 8) & 0xff00) |
                 ((((unsigned short)"김"[1]) << 0) & 0x00ff);

          FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &korWidth, &lineHeight);

      //}

      //[영문 문자폭 얻기]
      //{
          code = "A"[0];

          FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &engWidth, NULL);

      //}

  //}

  //[가상 문자 출력]
  //{
      //[설명]{----------------------
      //전달받은 문자열을 출력한다.
      //CRLF : 행을 바꾸어 준다.
      //'\t' : [공백] 으로 처리한다.
      //}----------------------------

      for(i = 0;
          //[문자열] 끝이 나올때 까지 계속 문자를 읽어서 출력한다.
          pStr[i] != '\0';
         )
      {
        if     (pStr[i] == '\t')
        {
          //[자동 행바꿈 상황인가?]
          //{
              //[2012.05.15.화][추가!!!]{---------------------------------------------------------
              //현재 [문자] 를 출력할 경우 지정 폭을 넘어간다면 <CRLF> 처리와 동일한 처리를 한다.
              //}---------------------------------------------------------------------------------

              if(pWidth > 0)
              {
                //[!]{-----------------------------------------------------------
                //<pWidth:0> 인 경우는 [자동 행바꿈] 을 적용하지 않고 일반 출력.
                //}--------------------------------------------------------------

                //[최대폭 검사]
                //{
                    //[2012.05.16.수][추가!!!]{------------------------------------------------
                    //[자동 줄바꿈] 이 적용되는 경우는 [행이 바뀌기 전] 에 이 행이 [최대폭]
                    //인지 확인한다.
                    //{ pWidth > 0 } 인 경우는 큰 의미는 없으나 정보는 정확하게 처리해 놓는다.
                    //이는 <pWidth> 가 문자폭보다 작은 값인 경우라도 [자동 줄바꿈] 기능으로
                    //다음 행에 출력은 되기 때문에 결과적으로 [세로 한줄] 로 출력되는데 이때는
                    //<maxWidth> 가 실제 출력폭으로 보다 정확한 값이 되기 때문이다.
                    //}------------------------------------------------------------------------

                    //현재 행의 [출력 폭] 이 [최대 값] 이라면 이 값을 최대값으로 지정.
                    if(maxWidth < width) { maxWidth = width; }

                //}

                if((width + engWidth) > pWidth)
                {
                  //다음 행의 좌표로 수정한다.
                  width   = 0;
                  height += lineHeight;

                }

              }

          //}

          //<tab> 은 "공백" 으로 처리한다.
          code = ' ';

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &moonjaWidh, &moonjaHeight) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          width += moonjaWidh;

          i++;

        }
        else if((pStr[i] == 0x0d) && (pStr[i+1] == 0x0a))
        {
          //[!]{-------------------------------------------------------------------------
          //CRLF 의 경우 문자는 출력하지 않고 CRLF 도 2byte-code 로 전달하여 현재 글꼴의
          //출력 행의 높이 정보를 얻어 height 위치만 수정한다.
          //}----------------------------------------------------------------------------

          //2byte-code 합성.
          code = 0x0d0a;

          //[문자] 는 출력되지 않으나 정보만 얻는다.(아래 함수 내부에서 자동 처리 됨.)
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &moonjaWidh, &moonjaHeight) != true)
          {
            return(false);

          }

          //[최대폭 검사]
          //{
              //[!]{-------------------------------------
              //<pWidth> 와 무관하게 계속 수집하면 된다.
              //단, <pWidth:0> 인 경우만 의미가 있다.
              //}----------------------------------------

              //이 행의 width 값이 현재까지 최대 값인지 검사한다.
              if(maxWidth < width)
              {
                //현재 값이 최대 값이라면 이 값을 다시 최대 값으로 저장한다.
                maxWidth = width;

              }

          //}

          //다음 행의 좌표로 수정한다.
          width   = 0;
          height += moonjaHeight;

          i += 2;

        }
        //[2011.08.21.일][수정!!!]{-----------------------------------------------------------------
        //통신으로 문자열이 전달되는 경우 한글이 2바이트중 첫번째 바이트만 오는 경우도있다.
        //이때, 이 저장소의 문자열을 출력하는 경우 무조건 +2 로 위치를 이동하면,
        //{ [한글첫번째바이트] + '\0' } 상태에서 '\0' 을 건너뛰에 되어 문자열이 제대로 출력되지
        //않게 된다.
        //따라서, 반드시 두개의 바이트를 전부 확인하여 각각이 모두 [음수] 인 경우만 [한글] 로 본다.
        //}-----------------------------------------------------------------------------------------
        else if((pStr[i] < 0) && (pStr[i + 1] < 0))
        //else if(pStr[i] < 0)
        {
          //[!]{--------------------------
          //2byte-code 인 경우.
          //[한글/기호/한자] 가 해당한다.
          //}-----------------------------

          //[자동 행바꿈 상황인가?]
          //{
              //[2012.05.15.화][추가!!!]{---------------------------------------------------------
              //현재 [문자] 를 출력할 경우 지정 폭을 넘어간다면 <CRLF> 처리와 동일한 처리를 한다.
              //}---------------------------------------------------------------------------------

              if(pWidth > 0)
              {
                //[!]{-----------------------------------------------------------
                //<pWidth:0> 인 경우는 [자동 행바꿈] 을 적용하지 않고 일반 출력.
                //}--------------------------------------------------------------

                //[최대폭 검사]
                //{
                    //[2012.05.16.수][추가!!!]{------------------------------------------------
                    //[자동 줄바꿈] 이 적용되는 경우는 [행이 바뀌기 전] 에 이 행이 [최대폭]
                    //인지 확인한다.
                    //{ pWidth > 0 } 인 경우는 큰 의미는 없으나 정보는 정확하게 처리해 놓는다.
                    //이는 <pWidth> 가 문자폭보다 작은 값인 경우라도 [자동 줄바꿈] 기능으로
                    //다음 행에 출력은 되기 때문에 결과적으로 [세로 한줄] 로 출력되는데 이때는
                    //<maxWidth> 가 실제 출력폭으로 보다 정확한 값이 되기 때문이다.
                    //}------------------------------------------------------------------------

                    //현재 행의 [출력 폭] 이 [최대 값] 이라면 이 값을 최대값으로 지정.
                    if(maxWidth < width) { maxWidth = width; }

                //}

                if((width + korWidth) > pWidth)
                {
                  //다음 행의 좌표로 수정한다.
                  width   = 0;
                  height += lineHeight;

                }

              }

          //}

          //2byte-code 합성.
          code = ((((unsigned short)pStr[i])   << 8) & 0xff00) |
                 ((((unsigned short)pStr[i+1]) << 0) & 0x00ff);

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &moonjaWidh, &moonjaHeight) != true)
          {
            return(false);

          }

          //[문자] 출력 좌표 수정.
          width += moonjaWidh;

          i += 2;

        }
        else
        {
          //[!]{----------------
          //1byte-code 인 경우.
          //[영문] 이 해당한다.
          //}-------------------

          //[자동 행바꿈 상황인가?]
          //{
              //[2012.05.15.화][추가!!!]{---------------------------------------------------------
              //현재 [문자] 를 출력할 경우 지정 폭을 넘어간다면 <CRLF> 처리와 동일한 처리를 한다.
              //}---------------------------------------------------------------------------------

              if(pWidth > 0)
              {
                //[!]{-----------------------------------------------------------
                //<pWidth:0> 인 경우는 [자동 행바꿈] 을 적용하지 않고 일반 출력.
                //}--------------------------------------------------------------

                //[최대폭 검사]
                //{
                    //[2012.05.16.수][추가!!!]{------------------------------------------------
                    //[자동 줄바꿈] 이 적용되는 경우는 [행이 바뀌기 전] 에 이 행이 [최대폭]
                    //인지 확인한다.
                    //{ pWidth > 0 } 인 경우는 큰 의미는 없으나 정보는 정확하게 처리해 놓는다.
                    //이는 <pWidth> 가 문자폭보다 작은 값인 경우라도 [자동 줄바꿈] 기능으로
                    //다음 행에 출력은 되기 때문에 결과적으로 [세로 한줄] 로 출력되는데 이때는
                    //<maxWidth> 가 실제 출력폭으로 보다 정확한 값이 되기 때문이다.
                    //}------------------------------------------------------------------------

                    //현재 행의 [출력 폭] 이 [최대 값] 이라면 이 값을 최대값으로 지정.
                    if(maxWidth < width) { maxWidth = width; }

                //}

                if((width + engWidth) > pWidth)
                {
                  //다음 행의 좌표로 수정한다.
                  width   = 0;
                  height += lineHeight;

                }

              }

          //}

          code = pStr[i];

          //[문자] 출력.
          if(FONT_Get_MoonjaOutAreaInfo(pFontPack, pStyle, code, &moonjaWidh, &moonjaHeight) != true)
          {
            return(false);
          }

          //[문자] 출력 좌표 수정.
          width += moonjaWidh;

          i++;

        }

      }

  //}

  //[최대폭 검사]
  //{
      //[!]{----------------------------------------------------------------------
      //마지막행이 CRLF 로 끝나지 않는 경우도 처리 되어야 하므로 한번더 처리한다.
      //이 행의 width 값이 현재까지 최대 값인지 검사한다.
      //
      //<pWidth> 와 무관하게 계속 수집하면 된다.
      //단, <pWidth:0> 인 경우만 의미가 있다.
      //}-------------------------------------------------------------------------

      if(maxWidth < width)
      {
        //현재 값이 최대 값이라면 이 값을 다시 최대 값으로 저장한다.
        maxWidth = width;

      }
      
  //}

  //[영역 정보 반환]
  //{
      //[!]{-------------------
      //NULL 이 아닌 경우만 처리.
      //}----------------------
      
      if(rWidth  != NULL) { (*rWidth)  = maxWidth;              }

      //행의경우는 마지막에 CRLF 로 끝나지 않을수도 있으므로 [행 한개] 높이를 더해준다.
      if(rHeight != NULL) { (*rHeight) = height + moonjaHeight; }
      
  //}

  return(true);

}








