diff options
author | Steffen Winterfeldt <wfeldt@opensuse.org> | 2009-09-30 14:54:50 +0200 |
---|---|---|
committer | Steffen Winterfeldt <wfeldt@opensuse.org> | 2009-09-30 14:54:50 +0200 |
commit | b1feb9139ac943da06da17e9ca5a90ae966f6820 (patch) | |
tree | 6874213a53fc424bbbdad11142b049457684958c | |
parent | d9375854f356c030e185f16f10839bab70f9c932 (diff) |
- log more data to allow easier font size adjustments
-rw-r--r-- | gfxboot-font.c | 326 |
1 files changed, 222 insertions, 104 deletions
diff --git a/gfxboot-font.c b/gfxboot-font.c index add1f38..50a9df5 100644 --- a/gfxboot-font.c +++ b/gfxboot-font.c @@ -32,6 +32,7 @@ struct option options[] = { { "add-charset", 1, NULL, 'c' }, { "font", 1, NULL, 'f' }, { "line-height", 1, NULL, 'l' }, + { "font-height", 1, NULL, 'H' }, { "font-path", 1, NULL, 'p' }, { "show", 0, NULL, 's' }, { "add-text", 1, NULL, 't' }, @@ -78,17 +79,24 @@ typedef struct font_s { int prop; int space_width; int dy; + unsigned index; + int height; + int baseline; list_t chars; /* n_set_t */ unsigned used:1; /* font is actually used */ unsigned ok:1; unsigned bold:1; unsigned nobitmap:1; unsigned autohint:2; /* 0: auto, 1: off, 2: on */ + unsigned autosize:1; + unsigned autoshift:1; } font_t; typedef struct char_data_s { struct char_data_s* next; unsigned ok:1; /* char exists */ + unsigned top:1; + unsigned bottom:1; int c; /* char (utf32) */ font_t *font; /* pointer to font */ int x_advance; @@ -104,6 +112,8 @@ typedef struct char_data_s { list_t font_list; /* font_t */ list_t char_list; /* char_data_t */ list_t chars_missing; /* n_set_t */ +list_t chars_top; /* n_set_t */ +list_t chars_bottom; /* n_set_t */ int font_height; int font_y_ofs; @@ -112,6 +122,7 @@ struct { int verbose; int test; int line_height; + int max_font_height; char *font_path; list_t chars; /* n_set_t */ char *file; @@ -143,6 +154,7 @@ int signed_bits(int num); int unsigned_bits(unsigned num); void encode_char(char_data_t *cd); int show_font(char *name); +void get_font_height(font_t *font, int *height, int *y_ofs); int main(int argc, char **argv) @@ -174,7 +186,7 @@ int main(int argc, char **argv) opterr = 0; - while((i = getopt_long(argc, argv, "a:c:f:l:p:st:v", options, NULL)) != -1) { + while((i = getopt_long(argc, argv, "Aa:c:f:H:l:p:st:v", options, NULL)) != -1) { switch(i) { case 'a': err = parse_int_list(&opt.chars, optarg); @@ -243,6 +255,14 @@ int main(int argc, char **argv) font->autohint = strtol(s, &s1, 0) + 1; if(*s1) err = 1; } + else if(!strcmp(str, "autosize")) { + font->autosize = strtol(s, &s1, 0); + if(*s1) err = 1; + } + else if(!strcmp(str, "autoshift")) { + font->autoshift = strtol(s, &s1, 0); + if(*s1) err = 1; + } else if(!strcmp(str, "c")) { err = parse_int_list(&font->chars, s); } @@ -265,6 +285,16 @@ int main(int argc, char **argv) } break; + case 'H': + str = optarg; + i = strtol(str, &str1, 0); + if(*str1 || i < 0) { + fprintf(stderr, "%s: invalid font height\n", str); + return 1; + } + opt.max_font_height = i; + break; + case 'l': str = optarg; i = strtol(str, &str1, 0); @@ -379,7 +409,8 @@ int main(int argc, char **argv) } // open all fonts - for(font = font_list.start; font; font = font->next) { + for(i = 0, font = font_list.start; font; font = font->next) { + font->index = i++; font->file_name = search_font(opt.font_path, font->name); if(font->file_name) { err = FT_New_Face(ft_lib, font->file_name, 0, &font->face); @@ -392,42 +423,11 @@ int main(int argc, char **argv) if( font->size && !FT_Set_Pixel_Sizes(font->face, font->size, 0) - ) font->ok = 1; - } - } - } - - // print some info - if(opt.verbose) { - printf("Font List\n"); - for(font = font_list.start; font; font = font->next) { - printf(" %s (%s)\n", font->name, font->ok ? "ok" : "not used"); - printf(" File %s\n", font->file_name); - printf(" Size %d", font->size); - if(font->dy) printf(", dY %d", font->dy); - if(font->prop) printf(", Prop %d", font->prop); - if(font->space_width) printf(", SpaceWidth %d", font->space_width); - printf("\n"); - if(font->chars.start) { - for(n = font->chars.start; n; n = n->next) { - printf(" c 0x%04x", n->first); - if(n->last != n->first) printf("-0x%04x", n->last); - printf("\n"); + ) { + font->ok = 1; } } } - printf("\n"); - } - - // print even more info - if(opt.verbose >= 2) { - printf("Requested Char List\n"); - for(n = opt.chars.start; n; n = n->next) { - printf(" 0x%04x", n->first); - if(n->last != n->first) printf("-0x%04x", n->last); - printf("\n"); - } - printf("\n"); } // build char list @@ -452,31 +452,50 @@ int main(int argc, char **argv) render_char(cd); } - FT_Done_FreeType(ft_lib); - // fix vertical glyph positions for(cd = char_list.start; cd; cd = cd->next) { if(cd->ok) cd->y_ofs += cd->font->dy; } + if(!opt.test) for(cd = char_list.start; cd; cd = cd->next) add_bbox(cd); + +// ############## + // get font dimensions - font_height = font_y_ofs = 0; - for(cd = char_list.start; cd; cd = cd->next) { - if(cd->y_ofs < font_y_ofs) font_y_ofs = cd->y_ofs; - i = cd->bitmap_height + cd->y_ofs; - if(i > font_height) font_height = i; + get_font_height(NULL, &font_height, &font_y_ofs); + + for(font = font_list.start; font; font = font->next) { + if(!font->ok) continue; + get_font_height(font, &i, &j); + font->height = i; + font->baseline = -j; } - font_height -= font_y_ofs; +// ############## - if(!opt.test) for(cd = char_list.start; cd; cd = cd->next) add_bbox(cd); + FT_Done_FreeType(ft_lib); + + // label largest chars + for(cd = char_list.start; cd; cd = cd->next) { + if(!cd->ok) continue; + if(cd->y_ofs - font_y_ofs + cd->bitmap_height >= font_height) cd->top = 1; + if(cd->y_ofs - font_y_ofs <= 0) cd->bottom = 1; + } for(cd = char_list.start; cd; cd = cd->next) make_prop(cd); - for(i = j = 0, cd = char_list.start; cd; cd = cd->next) { + for(cd = char_list.start; cd; cd = cd->next) { if(!cd->ok) insert_int_list(&chars_missing, cd->c, cd->c); } + for(cd = char_list.start; cd; cd = cd->next) { + if(cd->ok && cd->top) insert_int_list(&chars_top, cd->c, cd->c); + } + + for(cd = char_list.start; cd; cd = cd->next) { + if(cd->ok && cd->bottom) insert_int_list(&chars_bottom, cd->c, cd->c); + } + for(cd = char_list.start; cd; cd = cd->next) encode_char(cd); memset(&fh, 0, sizeof fh); @@ -488,6 +507,39 @@ int main(int argc, char **argv) for(cd = char_list.start; cd; cd = cd->next) if(cd->ok) fh.entries++; + // print font info + if(opt.verbose) { + printf("Font List\n"); + for(font = font_list.start; font; font = font->next) { + printf(" #%d %s (%s)\n", font->index, font->name, font->ok ? "ok" : "not used"); + printf(" File %s\n", font->file_name); + printf(" Size %d", font->size); + if(font->dy) printf(", dY %d", font->dy); + if(font->prop) printf(", Prop %d", font->prop); + if(font->space_width) printf(", SpaceWidth %d", font->space_width); + printf("\n"); + printf(" Height %d, Baseline %d\n", font->height, font->baseline); + if(font->chars.start) { + for(n = font->chars.start; n; n = n->next) { + printf(" c 0x%04x", n->first); + if(n->last != n->first) printf("-0x%04x", n->last); + printf("\n"); + } + } + } + printf("\n"); + } + + if(opt.verbose >= 2) { + printf("Requested Char List\n"); + for(n = opt.chars.start; n; n = n->next) { + printf(" 0x%04x", n->first); + if(n->last != n->first) printf("-0x%04x", n->last); + printf("\n"); + } + printf("\n"); + } + if(opt.verbose) { if(chars_missing.start) { printf("Missing Chars\n"); @@ -499,6 +551,26 @@ int main(int argc, char **argv) printf("\n"); } + if(chars_top.start) { + printf("Top Chars\n"); + for(n = chars_top.start; n; n = n->next) { + printf(" 0x%04x", n->first); + if(n->last != n->first) printf("-0x%04x", n->last); + printf("\n"); + } + printf("\n"); + } + + if(chars_bottom.start) { + printf("Bottom Chars\n"); + for(n = chars_bottom.start; n; n = n->next) { + printf(" 0x%04x", n->first); + if(n->last != n->first) printf("-0x%04x", n->last); + printf("\n"); + } + printf("\n"); + } + printf( "Font Size\n Height: %d\n Baseline: %d\n Line Height: %d\n\n", font_height, -font_y_ofs, fh.line_height @@ -583,9 +655,12 @@ void dump_char(char_data_t *cd) if(!cd || !cd->ok) return; - printf("Char 0x%04x '%s'\n", cd->c, utf32_to_utf8(cd->c)); + printf("Char 0x%04x '%s'", cd->c, utf32_to_utf8(cd->c)); + if(cd->top) printf(" top"); + if(cd->bottom) printf(" bottom"); + printf("\n"); - if(cd->font) printf(" Font: %s (%d)\n", cd->font->name, cd->font->size); + if(cd->font) printf(" Font: #%d %s (%d)\n", cd->font->index, cd->font->name, cd->font->size); printf( " Bitmap: %d x %d\n Advance: %d\n Offset: %d x %d\n", @@ -882,88 +957,107 @@ char *search_font(char *font_path, char *name) void render_char(char_data_t *cd) { - font_t *font; n_set_t *n; int err, glyph_index; FT_GlyphSlot glyph; int i, j; unsigned char uc; - for(font = font_list.start; font; font = font->next) { - if(!font->ok) continue; - if(font->chars.start) { - for(n = font->chars.start; n; n = n->next) { - if(cd->c >= n->first && cd->c <= n->last) break; - } - if(!n) continue; - } - glyph_index = FT_Get_Char_Index(font->face, cd->c); - if(!glyph_index) continue; + if(cd->ok) { + glyph_index = FT_Get_Char_Index(cd->font->face, cd->c); + if(!glyph_index) return; err = FT_Load_Char( - font->face, + cd->font->face, cd->c, FT_LOAD_RENDER | - (font->nobitmap ? FT_LOAD_NO_BITMAP : 0) | - (font->autohint ? font->autohint == 1 ? FT_LOAD_NO_AUTOHINT : FT_LOAD_FORCE_AUTOHINT : 0) + (cd->font->nobitmap ? FT_LOAD_NO_BITMAP : 0) | + (cd->font->autohint ? cd->font->autohint == 1 ? FT_LOAD_NO_AUTOHINT : FT_LOAD_FORCE_AUTOHINT : 0) ); - if(err) continue; + if(err) return; + } + else { + font_t *font; - cd->ok = 1; + for(font = font_list.start; font; font = font->next) { + if(!font->ok) continue; + if(font->chars.start) { + for(n = font->chars.start; n; n = n->next) { + if(cd->c >= n->first && cd->c <= n->last) break; + } + if(!n) continue; + } + + glyph_index = FT_Get_Char_Index(font->face, cd->c); + if(!glyph_index) continue; + + err = FT_Load_Char( + font->face, + cd->c, + FT_LOAD_RENDER | + (font->nobitmap ? FT_LOAD_NO_BITMAP : 0) | + (font->autohint ? font->autohint == 1 ? FT_LOAD_NO_AUTOHINT : FT_LOAD_FORCE_AUTOHINT : 0) + ); + if(err) continue; - cd->font = font; + cd->ok = 1; + cd->font = font; - glyph = font->face->glyph; - if(cd->font->bold) FT_GlyphSlot_Embolden(glyph); + break; + } + } - cd->bitmap_width = glyph->bitmap.width; - cd->bitmap_height = glyph->bitmap.rows; - cd->bitmap = new_mem(cd->bitmap_width * cd->bitmap_height); + if(!cd->ok) return; - cd->x_advance = glyph->advance.x / 64.; - cd->x_ofs = glyph->bitmap_left; - cd->y_ofs = glyph->bitmap_top - glyph->bitmap.rows; + glyph = cd->font->face->glyph; + if(cd->font->bold) FT_GlyphSlot_Embolden(glyph); - for(j = 0; j < cd->bitmap_height; j++) { - for(i = 0; i < cd->bitmap_width; i++) { - switch(glyph->bitmap.pixel_mode) { - case FT_PIXEL_MODE_MONO: - uc = ((glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] >> (7 - (i & 7))) & 1) * MAX_GRAY; - break; + cd->bitmap_width = glyph->bitmap.width; + cd->bitmap_height = glyph->bitmap.rows; + free(cd->bitmap); + cd->bitmap = new_mem(cd->bitmap_width * cd->bitmap_height); - case FT_PIXEL_MODE_GRAY: - uc = (glyph->bitmap.buffer[i + j * glyph->bitmap.pitch] * (MAX_GRAY + 1)) / (255 + 1); - break; + cd->x_advance = glyph->advance.x / 64.; + cd->x_ofs = glyph->bitmap_left; + cd->y_ofs = glyph->bitmap_top - glyph->bitmap.rows; - default: - uc = 0; - } - cd->bitmap[i + j * cd->bitmap_width] = uc; + for(j = 0; j < cd->bitmap_height; j++) { + for(i = 0; i < cd->bitmap_width; i++) { + switch(glyph->bitmap.pixel_mode) { + case FT_PIXEL_MODE_MONO: + uc = ((glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] >> (7 - (i & 7))) & 1) * MAX_GRAY; + break; + + case FT_PIXEL_MODE_GRAY: + uc = (glyph->bitmap.buffer[i + j * glyph->bitmap.pitch] * (MAX_GRAY + 1)) / (255 + 1); + break; + + default: + uc = 0; } + cd->bitmap[i + j * cd->bitmap_width] = uc; } + } #if 0 - printf( - "bitmap: mode %d, %d x %d, + %d x %d, advance %f x %f\n", - glyph->bitmap.pixel_mode, - glyph->bitmap.width, - glyph->bitmap.rows, - glyph->bitmap_left, - glyph->bitmap_top, - glyph->advance.x / 64., - glyph->advance.y / 64. - ); + printf( + "bitmap: mode %d, %d x %d, + %d x %d, advance %f x %f\n", + glyph->bitmap.pixel_mode, + glyph->bitmap.width, + glyph->bitmap.rows, + glyph->bitmap_left, + glyph->bitmap_top, + glyph->advance.x / 64., + glyph->advance.y / 64. + ); - printf( - "metrics:\n size %f x %f\n bearing %f x %f, advance %f\n", - glyph->metrics.width / 64., glyph->metrics.height / 64., - glyph->metrics.horiBearingX / 64., glyph->metrics.horiBearingY / 64., - glyph->metrics.horiAdvance / 64. - ); + printf( + "metrics:\n size %f x %f\n bearing %f x %f, advance %f\n", + glyph->metrics.width / 64., glyph->metrics.height / 64., + glyph->metrics.horiBearingX / 64., glyph->metrics.horiBearingY / 64., + glyph->metrics.horiAdvance / 64. + ); #endif - - break; - } } @@ -1028,6 +1122,10 @@ void add_bbox(char_data_t *cd) cd->bitmap_width = width; cd->bitmap_height = height; } + + if(!cd->bitmap_width || !cd->bitmap_height) { + cd->x_ofs = cd->y_ofs = 0; + } } @@ -1391,3 +1489,23 @@ int show_font(char *name) } +void get_font_height(font_t *font, int *height, int *y_ofs) +{ + int h, dy, i; + char_data_t *cd; + + // get font dimensions + h = dy = 0; + for(cd = char_list.start; cd; cd = cd->next) { + if(!cd->ok) continue; + if(font && cd->font != font) continue; + if(cd->y_ofs < dy) dy = cd->y_ofs; + i = cd->bitmap_height + cd->y_ofs; + if(i > h) h = i; + } + + *height = h - dy; + *y_ofs = dy; +} + + |