gxLib에서 폰트 사용에 문제가 있다는 말씀이 많아서 새로 수정해서 올립니다. gxLib를 처음 설계했을 때에는 임베디드용이라서 폰트 사용이 많지 않겠다고 생각했지만, 보통 3~4개의 폰트를 사용하시는 것으로 생각합니다. 특히 시간을 출력하는 부분을 포함하게 되면 문자열 출력 폰트와 시간 폰트를 계속 바꾸어 주어야 하는데 gx_set_font()는 매번 폰트 파일을 Open·Close하기 때문에 아무래도 부담이 되지요. 또한 제대로 Close가 안 되어서 메모리 문제가 발생한다는 말씀이 있어서 반드시 업그레이드를 해야 했습니다.


 

문제를 해결하기 위해 폰트를 선택할 때마다 폰트 파일을 Open·Close하는 것이 아니라 미리 사용할 폰트를 Open하여 폰트 핸들을 구하고 포트를 변경할 필요가 있을 경우 핸들을 지정하는 것만으로 간단히 처리하도록 한 것이죠. 이를 위해 dc_t에 폰트 관련 속성을 추가했습니다. *font는 폰트 핸들을, font_color은 폰트의 색상을 지정합니다.

 

typedef struct dc_t_ dc_t;
struct dc_t_
{
 char     dc_type;        // DC의 형태로 Screen, Bitmap, JPEG, PNG를 구분한다.
 int      width;          // 도트 단위의 폭
 int      height;         // 도트 단위의 높이
 int      dots;           // 전체 도트 갯수 width * height
 int      bytes;          // 메모리의 전체 Byte 크기
 int      colors;         // 칼라 깊이
 int      bytes_per_line; // 라인당 바이트 개수
 int      bits_per_pixel; // 비트당 픽셀 개수
 int      coor_x;         // 이전에 그리기 했던 마지막 좌표
 int      coor_y;         // 이전에 그리기 했던 마지막 좌표
 color_t  pen_color;      // 현재의 펜 칼라
 color_t  brush_color;    // 현재의 브러쉬 칼라
 color_t  font_color;     // 글씨 색상
 font_t  *font;           // 문자열 출력을 위한 글꼴 핸들
 void    *mapped;         // 메모리 매핑된 포인터

 void (*release_dc)( dc_t *dc);  // Device Context 소멸 및 관련 메모리를 삭제
 void (*clear    )( dc_t *dc, color_t color);   // 색으로 전체 칠하기
 void (*get_pixel)( dc_t *dc, int coor_x, int coor_y, color_t   *color ); // 칼라 값을 읽어 오기
 void (*set_pixel)( dc_t *dc, int coor_x, int coor_y, color_t    color ); // 점 찍기
 void (*hline    )( dc_t *dc, int x1st  , int x_2nd , int coor_y, color_t color);// 수평선 긋기
 void (*vline    )( dc_t *dc, int coor_x, int y_1st , int y_2nd , color_t color);// 수직선 긋기
};

 

압축 파일을 풀면 font_sample 이라는 샘플 디렉토리가 나옵니다. 디렉토리 안에 있는 sample.c 파일을 참고하세요. sample.c의 내용을 잠시 보겠습니다. main()을 보시면 두 개의 폰트를 미리 Open하는 것을 볼 수 있습니다. 폰트를 미리 open 한 후 텍스트를 출력하는 display_text()를 호출했습니다.

 

int   main  ( int argc, char *argv[]){

 gx_open( fb_dev_name);            // gxLib 초기화
 dc_screen = gx_get_screen_dc();   // 화면 출력을 위한 screen DC 구함
 dc_buffer = gx_get_compatible_dc( dc_screen) ));   // 화면 깜빡임을 없애기 위한 버퍼 DC

 gx_clear( dc_screen, gx_color( 0, 0, 0, 255));
 gx_clear( dc_buffer, gx_color( 0, 0, 0, 255));

 // 두 개의 폰트를 미리 open 합니다.
 hfont_1 = gx_open_font( "gulim12.bdf");
 hfont_2 = gx_open_font( "nbold32.bdf");

 while( 1){
     display_text();
     usleep( 100 * 1000);
 }

 gx_release_dc( dc_screen);
 gx_close();

 return   0;
}

 

disp_text() 함수에서는 gx_text_out()을 호출하기 전에 font와 font_color의 값을 변경함으로써 폰트와 색상을 변경합니다.

 

static void display_text( void){

 // 특정 지역 특정 색으로 채움
 gx_clear_area( dc_buffer, VIEW_LEFT, VIEW_TOP, VIEW_RIGHT, VIEW_BOTTOM, gx_color( 0, 0, 0, 255));

 // counter 출력
 dc_buffer->font = hfont_2;
 dc_buffer->font_color   = gx_color(    0, 255, 255, 255);
 gx_text_out( dc_buffer, VIEW_LEFT, VIEW_TOP+50, "counter=");

 sprintf( buff, "%d", ndx_counter++);
 dc_buffer->font = hfont_1;
 dc_buffer->font_color   = gx_color( 255,    0, 255, 255);
 gx_text_out( dc_buffer, VIEW_LEFT+190, VIEW_TOP+40, buff);

 // falinux 문자열 출력

 if ( ndx_counter % 5){
     dc_buffer->font = hfont_2;
     dc_buffer->font_color   = gx_color( 255, 255, 255, 255);
     gx_text_out( dc_buffer, VIEW_LEFT, VIEW_TOP+120, "www.falinux.com");
 }
 else {
     dc_buffer->font = hfont_1;
     dc_buffer->font_color   = gx_color( 255, 255, 0  , 255);
     gx_text_out( dc_buffer, VIEW_LEFT, VIEW_TOP+120, "---------------");
 }

 gx_bitblt( dc_screen, VIEW_LEFT, VIEW_TOP, dc_buffer, VIEW_LEFT, VIEW_TOP, VIEW_WIDTH, VIEW_HEIGHT);
}

 

이제 매번 gx_set_font()를 사용하여 폰트를 open할 필요가 없습니다. 아예 gx_set_font()를 제거했습니다. 폰트 사용이 많으시다면 gxLib 0.9.1을 사용하세요.