9 /* use builtin data, or dynamically load font data from X instead */
10 //#define BUILTIN_FONT_DATA
11 /* generate static font data code */
12 //#define WRITE_FONT_DATA
15 #ifdef WRITE_FONT_DATA
16 #undef BUILTIN_FONT_DATA
19 int zbitfont_t::font_refs = 0;
23 font_index(int style, int pen_size, int italics, int size)
25 if( pen_size > 0 ) --pen_size;
26 return ((size*2 + italics)*2 + pen_size)*7 + style;
29 #if defined(BUILTIN_FONT_DATA)
30 /* using static builtin font data */
32 zbitfont_t *zmpeg3_t::
33 bitfont(int style,int pen_size,int italics,int size)
35 int k = font_index(style,pen_size,italics,size);
36 return zbitfont_t::fonts[k];
40 chr_font(zchr_t *bp, int scale)
42 int size = bp->font_size + scale-1;
43 return bitfont(bp->font_style,bp->pen_size,bp->italics,size);
47 void zbitfont_t::init_fonts() {}
48 void zbitfont_t::destroy_fonts() {}
51 /* loading font data on the fly */
54 init_xfont(zbitfont_t *font,char *font_name)
56 const char *display_name = ":0";
57 Display *display = XOpenDisplay(display_name);
58 if( !display ) return 1;
59 Font font_id = XLoadFont(display,font_name);
61 XFontStruct *font_struct = XQueryFont(display,font_id);
62 if( !font_struct ) ret = 1;
64 int row_first = font_struct->min_char_or_byte2;
65 int row_last = font_struct->max_char_or_byte2;
66 int row_count = row_last-row_first + 1;
67 int col_first = font_struct->min_byte1;
68 int col_last = font_struct->max_byte1;
69 XCharStruct *per_char = font_struct->per_char;
70 XCharStruct *bounds = per_char == NULL ? NULL : &font_struct->max_bounds;
71 int row_sz, sizeof_data;
72 Screen *screen = DefaultScreenOfDisplay(display);
73 int depth = DefaultDepthOfScreen(screen);
74 Visual *visual = DefaultVisualOfScreen(screen);
75 Window w = DefaultRootWindow(display);
76 font->nch = (col_last-col_first+1) * (row_last-row_first+1);
77 font->chrs = new zbitchar_t[font->nch];
78 font->idx = font->idy = font->imy = 0;
84 unsigned int width, height;
88 gcv.function = GXcopy;
90 gcv.line_style = LineSolid;
92 n = GCFunction|GCForeground|GCLineWidth|GCLineStyle|GCFont;
93 gcv.foreground = BlackPixelOfScreen(DefaultScreenOfDisplay(display));
94 gcb = XCreateGC(display,w,n,&gcv);
95 gcv.foreground = WhitePixelOfScreen(DefaultScreenOfDisplay(display));
96 gcw = XCreateGC(display,w,n,&gcv);
98 for( b1=col_first; b1<=col_last; ++b1 ) {
99 for( b2=row_first; b2<=row_last; ++b2 ) {
100 int i = (b1-col_first)*row_count + b2-row_first;
101 zbitchar_t *cp = &font->chrs[i];
105 cp->ch = (b1<<8) + b2;
106 if( per_char != NULL )
107 bounds = &per_char[i];
108 cp->left = bounds->lbearing;
109 cp->right = bounds->rbearing;
110 cp->ascent = bounds->ascent;
111 cp->decent = bounds->descent;
112 width = cp->right - cp->left;
113 height = cp->ascent + cp->decent;
114 if( cp->ascent > font->imy ) font->imy = cp->ascent;
115 if( cp->decent > iny ) iny = cp->decent;
116 row_sz = (width+7) / 8;
117 sizeof_data = row_sz * height;
118 if( sizeof_data > 0 ) {
119 char *data = (char*)malloc(sizeof_data);
120 if( width > 0 ) { font->idx += width; ++inx; }
121 memset(&data[0],0,sizeof_data);
122 x = -cp->left; y = cp->ascent;
123 pixmap = XCreatePixmap(display,w,width,height,depth);
124 XFillRectangle(display,pixmap,gcb,0,0,width,height);
125 XDrawString16(display,pixmap,gcw,x,y,&ch,1);
126 image = XCreateImage(display,visual,1,XYBitmap,0,
127 data,width,height,8,row_sz);
128 XGetSubImage(display,pixmap,0,0,width,height,1,
130 cp->bitmap = new uint8_t [sizeof_data];
131 memcpy(&cp->bitmap[0],&data[0],sizeof_data);
132 XFreePixmap(display,pixmap);
133 XDestroyImage(image);
139 XFreeGC(display,gcb);
140 XFreeGC(display,gcw);
141 XFreeFont(display,font_struct);
142 if( inx == 0 ) inx = 1;
143 font->idx = (font->idx + inx-1) / inx;
144 font->idy = font->imy + iny;
146 XCloseDisplay(display);
151 get_xfont(int style, int pen_size, int italics, int size)
153 const char *family, *slant;
155 int serif = 0, prop = 0, casual = 0; // fst_default
157 case 1: serif = 1; prop = 0; casual = 0; break; // fst_mono_serif
158 case 2: serif = 1; prop = 1; casual = 0; break; // fst_prop_serif
159 case 3: serif = 0; prop = 0; casual = 0; break; // fst_mono_sans
160 case 4: serif = 0; prop = 1; casual = 0; break; // fst_prop_sans
161 case 5: serif = 1; prop = 1; casual = 1; break; // fst_casual
165 family = "adobe-utopia";
166 slant = italics ? "i" : "r";
170 (slant = italics ? "o" : "r", "urw-nimbus mono l") :
171 (slant = italics ? "i" : "r", "urw-nimbus sans l");
175 (slant = italics ? "i" : "r", "bitstream-courier 10 pitch"):
176 (slant = italics ? "i" : "r", "bitstream-bitstream charter");
179 family = "bitstream-bitstream charter";
182 const char *wght = pen_size > 1 ? "bold" : "medium";
184 // range expanded to account for scale
185 if( size < 0 ) size = 0;
186 if( size > MAX_SIZE ) size = MAX_SIZE;
189 case 0: ptsz = 48; break; // very fsz_small
190 case 1: ptsz = 100; break; // fsz_small
191 default: case 2: break; // fsz_normal
192 case 3: ptsz = 320; break; // fsz_large
193 case 4: ptsz = 420; break; // very fsz_large
197 sprintf(&name[0],"-%s-%s-%s-*-*-*-0-%d-%d-*-*-iso8859-1",
198 family, wght, slant, ptsz, ptsz);
199 zbitfont_t *font = new zbitfont_t();
200 if( init_xfont(font,&name[0]) ) {
201 delete font; font = 0;
206 /* italics=2, pen_size=2, font_size=5, font_style=7 */
207 int zbitfont_t::total_fonts = 140;
208 zbitfont_t *zbitfont_t::fonts[140];
210 zbitfont_t *zmpeg3_t::
211 bitfont(int style,int pen_size,int italics,int size)
213 int k = font_index(style,pen_size,italics,size);
214 bitfont_t *font = bitfont_t::fonts[k];
216 font = get_xfont(style,pen_size,italics,size);
217 bitfont_t::fonts[k] = font;
223 chr_font(zchr_t *bp, int scale)
225 int size = bp->font_size + scale-1;
226 return bitfont(bp->font_style,bp->pen_size,bp->italics,size);
234 for( int i=0; i<total_fonts; ++i ) fonts[i] = 0;
241 if( font_refs > 0 ) --font_refs;
242 if( font_refs > 0 ) return;
243 for( int i=0; i<total_fonts; ++i )
244 if( fonts[i] ) { delete fonts[i]; fonts[i] = 0; }
247 void zbitfont_t::init_fonts() {}
248 void zbitfont_t::destroy_fonts() {}
253 for( int i=0; i<total_fonts; ++i ) fonts[i] = 0;
258 for( int i=0; i<total_fonts; ++i )
259 if( fonts[i] ) { delete fonts[i]; fonts[i] = 0; }
262 zstatic_init_t static_init;
267 #if defined(WRITE_FONT_DATA)
268 /* generate code for builtin font initialization */
271 write_font(int fno, zbitfont_t *font)
275 sprintf(&font_var[0],"font%02d",fno);
276 printf("#include \"libzmpeg3.h\"\n\n");
277 zbitchar_t *cp = font->chrs;
278 for( int i=0; i<font->nch; ++i,++cp ) {
279 int sizeof_data = (cp->right-cp->left+7)/8 * (cp->ascent+cp->decent);
280 if( sizeof_data > 0 ) {
281 printf("static uint8_t %s_pix%04x[] = {\n",font_var,i);
282 uint8_t *bp = cp->bitmap;
284 while( j < sizeof_data ) {
285 if( (j&7) == 0 ) printf(" ");
286 printf("0x%02x,",*bp++);
287 if( (++j&7) == 0 ) printf("\n");
289 if( (j&7) != 0 ) printf("\n");
295 printf("static zbitchar_t %s_chrs[] = {\n",font_var);
297 for( int i=0; i<font->nch; ++i,++cp ) {
298 printf(" { 0x%04x, %2d, %2d, %2d, %2d, ",
299 cp->ch,cp->left,cp->right,cp->ascent,cp->decent);
300 int sizeof_data = (cp->right-cp->left+7)/8 * (cp->ascent+cp->decent);
301 if( sizeof_data > 0 )
302 printf("&%s_pix%04x[0] },\n",font_var,i);
309 printf("static zbitfont_t %s = { &%s_chrs[0], %d, %d, %d, %d, };\n",
310 font_var,font_var,font->nch,font->idx,font->idy,font->imy);
315 int main(int ac, char **av)
318 for( int size=0; size<=MAX_SIZE; ++size ) {
319 for( int italics=0; italics<=1; ++italics ) {
320 for( int pen_size=1; pen_size<=2; ++pen_size ) {
321 for( int font_style=0; font_style<=6; ++font_style ) {
322 zbitfont_t *font = get_xfont(font_style, pen_size, italics, size);
323 write_font(++fno, font);
330 printf("zbitfont_t *zbitfont_t::fonts[] = {\n");
331 for( int size=0; size<=MAX_SIZE; ++size ) {
332 for( int italics=0; italics<=1; ++italics ) {
333 for( int pen_size=1; pen_size<=2; ++pen_size ) {
334 for( int font_style=0; font_style<=6; ++font_style ) {
335 if( (fno&7) == 0 ) printf(" ");
336 printf("&font%02d,",++fno);
337 if( (fno&7) == 0 ) printf("\n");
342 if( (fno&7) != 0 ) printf("\n");
345 printf("int zbitfont_t::total_fonts = %d;\n",fno);
353 /* attach to end of output for testing */
354 int main(int ac, char **av)
357 for( int i=0; i<zbitfont_t::total_fonts; ++i ) {
358 zbitfont_t *font = zbitfont_t::fonts[i];
359 for( int ch=0; ch<font->nch; ++ch ) {
360 zbitchar_t *cp = &font->chrs[ch];
361 sz += 16 + (cp->ascent+cp->decent)*((cp->right-cp->left+7)/8);
365 printf(" %d bytes\n",sz);
366 zbitchar_t *cp = &font84.chrs['y'];
367 uint8_t *bmap = cp->bitmap;
368 int wd = cp->right - cp->left;
369 int ht = cp->ascent + cp->decent;
370 int wsz = (wd+7) / 8;
371 for( int iy=0; iy<ht; ++iy ) {
372 uint8_t *row = &bmap[iy*wsz];
373 for( int ix=0; ix<wd; ++ix ) {
374 int ch = ((row[ix>>3] >> (ix&7)) & 1) ? 'x' : ' ';