GD-custom: Hints

Builtin Kanji Font

Mordern GD, a library for graphic, supports 16bit charactor fonts and TrurType Font. However, it is not provide such fonts. Then, user should attach fonts their want. This page describes a trial of font attatchement under such background.

NOTE: Momes belows are not elegant solution. I think, it is a bad example. You should try another way.

When I try to use kanji in GD. I have two way. First, 16bit charactor fonts. These font have to attached in compile time. According to given string, my program have to switch functions ( gdImageString() and gdImageString16() ). It is burdensome.

Second choice is TTF. This way is useful because it is not required attachment in compiling. However, it is not suits to small fonts (under 20dots) because drawing results of small font require high discrimination.

Sample of Small Size Built-in Japanese Fonts

My Apporoach

ASCII-EUC mixing

Following function depicts a horizontal drawing of ASCII-Japanese mix string. The function expects

BGD_DECLARE(void) gdImageStringX (gdImagePtr im, gdFontPtr af, gdFontPtr ef, int x, int y, unsigned char *s, int color) { unsigned char *c1; unsigned short cd; c1 = s; while(*c1) { if(*c1 & 0x80) { cd = ((*c1 & 0x7f) << 8) | (*(c1+1) & 0x7f); gdImageChar (im, ef, x, y, cd, color); x += ef->w; c1++; c1++; } else { gdImageChar (im, af, x, y, *c1, color); x += af->w; c1++; } } }

Font Data Compression

GD use bytemap (1 byte/pixel) to store letter glyphs. It requires memory to compile and use them. If it use bitmap (1 bit/pixel), the memory problem will improved.

typedef struct { /* # of characters in font */ int nchars; /* First character is numbered... (usually 32 = space) */ int offset; /* Character width and height */ int w; int h; /* Font data; array of characters, one row after another. Easily included in code, also easily loaded from data files. */ char *data; /* original data format (bytemap) */ unsigned char *cdata; /* compressed data (bitmap) */ } gdFont;

Drawing is implemented following function.

BGD_DECLARE(void) gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y, int c, int color) { int cx, cy; int px, py; int fline; int charbytelen; unsigned char* charpos; cx = 0; cy = 0; #ifdef CHARSET_EBCDIC c = ASC (c); #endif /*CHARSET_EBCDIC */ if ((c < f->offset) || (c >= (f->offset + f->nchars))) { return; } fline = (c - f->offset) * f->h * f->w; charbytelen = (f->w*f->h+7)/8; charpos = NULL; for (py = y; (py < (y + f->h)); py++) { for (px = x; (px < (x + f->w)); px++) { /* have compressed data (bitmap) */ if(f->cdata) { charpos = &f->cdata[(c - f->offset)*charbytelen]; if( (charpos[(cy*f->w + cx)/8] >> (7- (cy*f->w + cx)%8)) & 0x01) { gdImageSetPixel (im, px, py, color); } } else { /* check uncompressed data (bytemap) */ if (f->data[fline + cy * f->w + cx]) { gdImageSetPixel (im, px, py, color); } } cx++; } cx = 0; cy++; } }

K Chinen, JAIST.