그래픽 & 멀티미디어
gxLib에서 폰트 사용에 문제가 있다는 말씀이 많아서 새로 수정해서 올립니다. gxLib를 처음 설계했을 때에는 임베디드용이라서 폰트 사용이 많지 않겠다고 생각했지만, 보통 3~4개의 폰트를 사용하시는 것으로 생각합니다. 특히 시간을 출력하는 부분을 포함하게 되면 문자열 출력 폰트와 시간 폰트를 계속 바꾸어 주어야 하는데 gx_set_font()는 매번 폰트 파일을 Open·Close하기 때문에 아무래도 부담이 되지요. 또한 제대로 Close가 안 되어서 메모리 문제가 발생한다는 말씀이 있어서 반드시 업그레이드를 해야 했습니다.
- Download: gxlib_0.9.1.tar.gz
문제를 해결하기 위해 폰트를 선택할 때마다 폰트 파일을 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을 사용하세요.
gxlib_0.9.1 에는 gx_layer_move() 와 gx_layer_move_to() 함수가 빠져있던데... 버전업되면서 빠지는 건가요?