diff options
author | 1 <alexl@redhat.com> | 2000-12-01 17:14:29 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2000-12-01 17:14:29 +0000 |
commit | f3e06d23bf463fa56077f8061fed2e8c0ed16bd9 (patch) | |
tree | 7037d0857e024f5a0a87898cd1d24cc27ab08667 /gdk/linux-fb/gdkpango-fb.c | |
parent | 97bfa3300d2295c37548377bb7b32d3f696bed3c (diff) | |
download | gdk-pixbuf-f3e06d23bf463fa56077f8061fed2e8c0ed16bd9.tar.gz |
Note: GtkFB now requires Freetype 2 final.
2000-12-01 <alexl@redhat.com>
* gdk/linux-fb/Makefile.am:
* modules/linux-fb/Makefile.am:
Freetype 2 final uses freetype-config
* gdk/linux-fb/gdkpango-fb.c:
Upgrade to use Freetype 2 final.
More flexible support for font aliases, this also fixes a bug with
GtkFontSelector, as the aliases must be visible in the font/family list,
or GtkFontSelector reads uninitialized memory.
Diffstat (limited to 'gdk/linux-fb/gdkpango-fb.c')
-rw-r--r-- | gdk/linux-fb/gdkpango-fb.c | 271 |
1 files changed, 195 insertions, 76 deletions
diff --git a/gdk/linux-fb/gdkpango-fb.c b/gdk/linux-fb/gdkpango-fb.c index 622521247..c0b054f00 100644 --- a/gdk/linux-fb/gdkpango-fb.c +++ b/gdk/linux-fb/gdkpango-fb.c @@ -10,9 +10,9 @@ #include <freetype/freetype.h> #include <freetype/ftglyph.h> -#include <freetype/ftgrays.h> + #if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2 -#error "We need Freetype 2.0 (beta?)" +#error "We need Freetype 2.0" #endif #define PANGO_RENDER_TYPE_FB "PangoRenderTypeFB" @@ -39,15 +39,112 @@ typedef struct { FT_Library gdk_fb_ft_lib = NULL; -#define USE_FTGRAYS +#define MAX_ALIASES 3 + +typedef struct { + PangoFontDescription alias; + PangoFontDescription descriptions[MAX_ALIASES]; +} PangoFBAlias; + +static PangoFBAlias alias_table[] = +{ + /* sans: */ + { + {"Sans", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + { + {"Arial", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + {"URW Gothic L", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Sans", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + { + {"Arial", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + {"URW Gothic L", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Sans", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + { + {"Arial", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + {"URW Gothic L", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Sans", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + { + {"Arial", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + {"URW Gothic L", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + } + }, + + /* serif: */ + { + {"Serif", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + { + {"Times New Roman", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + {"URW Bookman L", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Serif", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + { + {"Times New Roman", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + {"URW Bookman L", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Serif", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + { + {"Times New Roman", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + {"URW Bookman L", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Serif", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + { + {"Times New Roman", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + {"URW Bookman L", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + } + }, + + /* monospace: */ + { + {"Monospace", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + { + {"Courier New", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + {"Courier", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Monospace", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + { + {"Courier New", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + {"Courier", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Monospace", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + { + {"Courier New", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + {"Courier", PANGO_STYLE_NORMAL, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + } + }, + { + {"Monospace", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + { + {"Courier New", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + {"Courier", PANGO_STYLE_OBLIQUE, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL}, + } + }, +}; + +#define ALIAS_TABLE_LEN (sizeof(alias_table)/sizeof(PangoFBAlias)) void gdk_fb_font_init (void) { FT_Init_FreeType (&gdk_fb_ft_lib); -#ifdef USE_FTGRAYS - FT_Set_Raster (gdk_fb_ft_lib, &ft_grays_raster); /* If this is removed, also turn off USE_FTGRAYS define in gdkdrawable-fb2.c */ -#endif } void @@ -106,65 +203,97 @@ pango_fb_font_map_get_type (void) return object_type; } +static gboolean +pango_font_description_equal_nosize (const PangoFontDescription *d1, + const PangoFontDescription *d2) +{ + return + (g_strcasecmp (d1->family_name, d2->family_name)==0) && + d1->style == d2->style && + d1->variant == d2->variant && + d1->weight == d2->weight && + d1->stretch == d2->stretch; +} + + static PangoFont * -pango_fb_font_map_load_font (PangoFontMap *fontmap, - const PangoFontDescription *desc) +pango_fb_lookup_descr (PangoFontMap *fontmap, + const PangoFontDescription *desc, + const PangoFontDescription *save_as) { PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap; PangoFBFont *retval; PangoFBFontListing *fl = NULL; int i; - PangoFontDescription d2; - - /* XXX fixme badhack */ - if (!strcasecmp (desc->family_name, "sans")) - { - d2 = *desc; - d2.family_name = "Arial"; - desc = &d2; - } - /* XXX fixme badhack */ - if (!strcasecmp (desc->family_name, "serif")) - { - d2 = *desc; - d2.family_name = "Times New Roman"; - desc = &d2; - } retval = g_hash_table_lookup (fbfm->all_fonts, desc); if (retval) { g_object_ref (G_OBJECT(retval)); - goto out; + return (PangoFont *)retval; } for (i = 0; i < fbfm->all_descs->len; i++) { fl = g_ptr_array_index (fbfm->all_descs, i); - /* Can't use pango_font_description_equal() because it checks ->size as well */ - if (!g_strcasecmp (desc->family_name, fl->desc.family_name) && - desc->style == fl->desc.style && - desc->weight == fl->desc.weight && - desc->stretch == fl->desc.stretch) + if (pango_font_description_equal_nosize(desc, &fl->desc)) break; } + if (i >= fbfm->all_descs->len) return NULL; retval = (PangoFBFont *)g_object_new (PANGO_TYPE_FB_FONT, NULL); - retval->desc = *desc; - retval->desc.family_name = g_strdup (desc->family_name); + retval->desc = *save_as; + retval->desc.family_name = g_strdup (save_as->family_name); retval->ftf = fl->ftf; g_hash_table_insert (fbfm->all_fonts, &retval->desc, retval); - g_object_ref (G_OBJECT (retval)); /* XXX FIXME: We have to keep the font in the cache forever because I'm too clueless to see + g_object_ref (G_OBJECT (retval)); /* XXX FIXME: We have to keep the font in the cache + forever because I'm too clueless to see signals in gobject */ - out: return (PangoFont *)retval; + +} + +static PangoFont * +pango_fb_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *desc) +{ + PangoFont *font; + const PangoFontDescription *descs; + const PangoFontDescription *alias; + int i, j; + + font = pango_fb_lookup_descr (fontmap, desc, desc); + + if (font) + return font; + + for (i=0;i<ALIAS_TABLE_LEN;i++) + { + alias = &alias_table[i].alias; + + if (pango_font_description_equal_nosize (desc, alias)) + { + descs = &alias_table[i].descriptions[0]; + j = 0; + while ((j < MAX_ALIASES) && + (descs[j].family_name != NULL)) + { + font = pango_fb_lookup_descr (fontmap, &descs[j], desc); + if (font) + return font; + j++; + } + return NULL; + } + } + return NULL; } static void @@ -204,8 +333,6 @@ list_fonts (PangoFBFontMap *fm, if (ec) break; /* error opening */ - FT_Select_Charmap (ftf, ft_encoding_unicode); - n = ftf->num_faces; if (!ftf->family_name || !ftf->style_name) @@ -293,8 +420,8 @@ pango_fb_font_map_list_fonts (PangoFontMap *fontmap, PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap; int i, n; - *descs = g_new (PangoFontDescription *, fbfm->all_descs->len); - *n_descs = fbfm->all_descs->len; + *descs = g_new (PangoFontDescription *, fbfm->all_descs->len + ALIAS_TABLE_LEN); + *n_descs = fbfm->all_descs->len + ALIAS_TABLE_LEN; for (i = n = 0; i < fbfm->all_descs->len; i++) { @@ -305,6 +432,15 @@ pango_fb_font_map_list_fonts (PangoFontMap *fontmap, (*descs)[n++] = pango_font_description_copy (pfd); } + for (i = 0; i < ALIAS_TABLE_LEN; i++) + { + PangoFontDescription *pfd = &alias_table[i].alias; + + if (strcasecmp (family, pfd->family_name)) + continue; + + (*descs)[n++] = pango_font_description_copy (pfd); + } *n_descs = n; *descs = g_realloc (*descs, n * sizeof(PangoFontDescription *)); } @@ -327,15 +463,26 @@ pango_fb_font_map_list_families (PangoFontMap *fontmap, int *n_families) { PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap; - int i; GHashTable *thash = g_hash_table_new (g_str_hash, g_str_equal); struct famlist stickittome; + gchar *family_name; + int i; + /* Use a temporary hashtable to uniqueify the family names. */ + for(i = 0; i < fbfm->all_descs->len; i++) { PangoFBFontListing *fl = g_ptr_array_index (fbfm->all_descs, i); - g_hash_table_insert (thash, fl->desc.family_name, fl); + family_name = fl->desc.family_name; + g_hash_table_insert (thash, family_name, family_name); + } + + for(i = 0; i < ALIAS_TABLE_LEN; i++) + { + family_name = alias_table[i].alias.family_name; + g_hash_table_insert (thash, family_name, family_name); } + *n_families = g_hash_table_size (thash); *families = g_new (gchar *, *n_families); @@ -476,7 +623,7 @@ pango_fb_font_get_glyph_info (PangoFont *font, PangoGlyph glyph) FT_GlyphSlot g; PangoRectangle *my_logical_rect, *my_ink_rect; FT_Face ftf; - gboolean free_buffer = FALSE; + FT_Error ec; ftf = fbf->ftf; @@ -488,35 +635,17 @@ pango_fb_font_get_glyph_info (PangoFont *font, PangoGlyph glyph) pgi = g_new0 (PangoFBGlyphInfo, 1); - FT_Load_Glyph (ftf, glyph, FT_LOAD_DEFAULT); + ec = FT_Load_Glyph (ftf, glyph, FT_LOAD_DEFAULT); g = ftf->glyph; if (g->format != ft_glyph_format_bitmap) - { - FT_BitmapGlyph bgy; - int bdepth; - -#if defined(USE_AA) || 1 -#ifdef USE_FTGRAYS - bdepth = 256; -#else - bdepth = 128; -#endif -#else - bdepth = 0; -#endif - - if (FT_Get_Glyph_Bitmap(ftf, glyph, 0, bdepth, NULL, &bgy)) - g_error ("Glyph render failed"); - - renderme = &bgy->bitmap; - pgi->top = bgy->top; - pgi->left = bgy->left; - free_buffer = TRUE; - } - else - renderme = &g->bitmap; + if ((ec = FT_Render_Glyph(g, ft_render_mode_normal))) + g_warning ("Glyph render failed: %d", ec); + + renderme = &g->bitmap; + pgi->top = g->bitmap_top; + pgi->left = g->bitmap_left; pgi->fbd.drawable_data.mem = g_memdup (renderme->buffer, renderme->pitch * renderme->rows); pgi->fbd.drawable_data.rowstride = renderme->pitch; @@ -529,11 +658,7 @@ pango_fb_font_get_glyph_info (PangoFont *font, PangoGlyph glyph) pgi->fbd.drawable_data.depth = 1; break; case ft_pixel_mode_grays: -#if defined(USE_FTGRAYS) pgi->fbd.drawable_data.depth = 78; -#else - pgi->fbd.drawable_data.depth = 77; -#endif break; default: g_assert_not_reached (); @@ -666,12 +791,6 @@ pango_fb_font_find_shaper (PangoFont *font, return (PangoEngineShape *)pango_map_get_engine (shape_map, ch); } -#if 0 -/* freetype.h doesn't declare it, doh */ -EXPORT_FUNC(FT_Error) FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot* aslot ); -#endif - void pango_fb_font_set_size (PangoFont *font) { |