Commit 2a1b3edd authored by Elliot Lee's avatar Elliot Lee Committed by Elliot Lee

Fix conditionality to work the "right" way. Missed commits from previous.



2000-06-18  Elliot Lee  <sopwith@redhat.com>

* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
parent df4fc367
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
2000-06-18 Elliot Lee <sopwith@redhat.com>
* gdk/Makefile.am, gdk/*/Makefile.am: Fix conditionality to work the "right" way.
* gtk/gtk{plug,socket}.h: Missed commits from previous.
2000-06-20 Havoc Pennington <hp@redhat.com>
* modules/linux-fb/Makefile.am: Make this compile
......
## Makefile.am for gtk+/gdk
SUBDIRS=x11 win32 nanox linux-fb
SUBDIRS=$(gdktarget)
DIST_SUBDIRS=linux-fb nanox win32 x11
EXTRA_DIST = \
gdkconfig.h.win32 \
......
......@@ -19,12 +19,7 @@ LDFLAGS = @STRIP_BEGIN@ \
-lm \
@STRIP_END@
if USE_LINUX_FB
noinst_LTLIBRARIES = libgdk-linux-fb.la
noinst_PROGRAMS=#test-fb
#test_fb_LDFLAGS=../libgdk.la libgdk-linux-fb.la
libgdk_linux_fb_la_SOURCES = \
gdkcolor-fb.c \
......@@ -61,7 +56,3 @@ libgdk_linux_fb_la_SOURCES = \
mispans.c \
gdkpango-fb.c
mispans.c
else
noinst_LTLIBRARIES =
endif
#include <glib.h>
#include "gdkprivate-fb.h"
#include "gdkpango.h"
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <pango/pango.h>
#include <pango/pango-modules.h>
#include <freetype/freetype.h>
#include <freetype/ftgrays.h>
#if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2
#error "We need Freetype 2.0 (beta?)"
#endif
#define PANGO_RENDER_TYPE_FB "PangoRenderTypeFB"
typedef struct {
PangoFontMap parent_instance;
GPtrArray *all_descs;
GHashTable *all_fonts;
int n_fonts;
double resolution;
} PangoFBFontMap;
typedef struct {
PangoFontMapClass parent_class;
} PangoFBFontMapClass;
typedef struct {
PangoFontDescription desc;
FT_Face ftf;
} PangoFBFontListing;
FT_Library gdk_fb_ft_lib = NULL;
void
gdk_fb_font_init(void)
{
FT_Init_FreeType(&gdk_fb_ft_lib);
#if 0
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
gdk_fb_font_fini(void)
{
FT_Done_FreeType(gdk_fb_ft_lib);
}
static void pango_fb_font_map_init(PangoFBFontMap *fontmap);
static PangoFont *pango_fb_font_map_load_font(PangoFontMap *fontmap,
const PangoFontDescription *desc);
static void pango_fb_font_map_list_fonts(PangoFontMap *fontmap,
const gchar *family,
PangoFontDescription ***descs,
int *n_descs);
static void pango_fb_font_map_list_families(PangoFontMap *fontmap,
gchar ***families,
int *n_families);
static void
pango_fb_font_map_class_init(PangoFBFontMapClass *class)
{
class->parent_class.load_font = pango_fb_font_map_load_font;
class->parent_class.list_fonts = pango_fb_font_map_list_fonts;
class->parent_class.list_families = pango_fb_font_map_list_families;
}
GType
pango_fb_font_map_get_type(void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (PangoFBFontMapClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) pango_fb_font_map_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (PangoFBFontMap),
0, /* n_preallocs */
(GInstanceInitFunc) pango_fb_font_map_init,
};
object_type = g_type_register_static (PANGO_TYPE_FONT_MAP,
"PangoFBFontMap",
&object_info);
}
return object_type;
}
static PangoFont *
pango_fb_font_map_load_font(PangoFontMap *fontmap,
const PangoFontDescription *desc)
{
PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap;
PangoFBFont *retval;
PangoFBFontListing *fl;
int i;
PangoFontDescription d2;
/* XXX fixme badhack */
if(!strcasecmp(desc->family_name, "sans"))
{
d2 = *desc;
d2.family_name = "Arial";
desc = &d2;
}
retval = g_hash_table_lookup(fbfm->all_fonts, desc);
if(retval)
{
g_object_ref(G_OBJECT(retval));
goto out;
}
for(i = 0; i < fbfm->all_descs->len; i++)
{
fl = g_ptr_array_index(fbfm->all_descs, i);
/* Can't use pango_font_description_compare() 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)
break;
}
if(i >= fbfm->all_descs->len)
return NULL;
retval = (PangoFBFont *)g_type_create_instance(PANGO_TYPE_FB_FONT);
retval->desc = *desc;
retval->desc.family_name = g_strdup(desc->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
signals in gobject */
out:
return (PangoFont *)retval;
}
static void
list_fonts(PangoFBFontMap *fm, const char *family,
GPtrArray *descs, const char *dir)
{
DIR *dirh;
struct dirent *dent;
dirh = opendir(dir);
if(!dirh)
return;
while((dent = readdir(dirh)))
{
PangoFBFontListing *pfd;
char *ctmp;
char buf[1024];
FT_Face ftf;
FT_Error ec;
int i = 0, n = 1;
ctmp = strrchr(dent->d_name, '.');
if(!ctmp
|| (strcasecmp(ctmp, ".ttf")
&& strcasecmp(ctmp, ".pfa")
&& strcasecmp(ctmp, ".pfb")))
continue;
g_snprintf(buf, sizeof(buf), "%s/%s", dir, dent->d_name);
while(i < n)
{
ec = FT_New_Face(gdk_fb_ft_lib, buf, i, &ftf);
if(ec)
continue; /* error opening */
FT_Select_Charmap(ftf, ft_encoding_unicode);
n = ftf->num_faces;
if(!ftf->family_name || !ftf->style_name)
{
g_warning("No family/style on %s", buf);
FT_Done_Face(ftf);
i = n;
continue;
}
g_message("Typeface %s/%s", ftf->family_name, ftf->style_name);
pfd = g_new0(PangoFBFontListing, 1);
/* Now add the item */
pfd->desc.family_name = g_strdup(ftf->family_name);
pfd->desc.style = PANGO_STYLE_NORMAL;
pfd->desc.variant = PANGO_VARIANT_NORMAL;
pfd->desc.weight = PANGO_WEIGHT_NORMAL;
pfd->desc.stretch = PANGO_STRETCH_NORMAL;
if(ftf->style_name)
{
char lcstr[512];
strcpy(lcstr, ftf->style_name);
g_strdown(lcstr);
if(strstr(lcstr, "italic"))
pfd->desc.style = PANGO_STYLE_ITALIC;
else if(strstr(lcstr, "oblique"))
pfd->desc.style = PANGO_STYLE_OBLIQUE;
if(strstr(lcstr, "bold"))
pfd->desc.weight = PANGO_WEIGHT_BOLD;
if(strstr(lcstr, "condensed"))
pfd->desc.stretch = PANGO_STRETCH_CONDENSED;
else if(strstr(lcstr, "expanded"))
pfd->desc.stretch = PANGO_STRETCH_EXPANDED;
}
pfd->ftf = ftf;
g_ptr_array_add(descs, pfd);
i++;
}
}
}
static guint
pango_font_description_hash(gconstpointer a)
{
const PangoFontDescription *fa = a;
return g_str_hash(fa->family_name) ^ (fa->style + fa->weight + fa->stretch + fa->variant + fa->size);
}
static void
pango_fb_font_map_init(PangoFBFontMap *fontmap)
{
static const char *font_dirs[] = {
"/usr/share/fonts/default/TrueType",
"/usr/share/fonts/default/Type1",
"/usr/lib/X11/fonts/TrueType",
"/usr/lib/X11/fonts/Type1",
NULL
};
int i;
fontmap->all_fonts = g_hash_table_new(pango_font_description_hash, (GCompareFunc)pango_font_description_compare);
fontmap->all_descs = g_ptr_array_new();
for(i = 0; font_dirs[i]; i++)
list_fonts(fontmap, NULL, fontmap->all_descs, font_dirs[i]);
}
static void
pango_fb_font_map_list_fonts(PangoFontMap *fontmap,
const gchar *family,
PangoFontDescription ***descs,
int *n_descs)
{
PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap;
int i, n;
*descs = g_new(PangoFontDescription *, fbfm->all_descs->len);
*n_descs = fbfm->all_descs->len;
for(i = n = 0; i < fbfm->all_descs->len; i++)
{
PangoFontDescription *pfd = g_ptr_array_index(fbfm->all_descs, i);
if(strcasecmp(family, pfd->family_name))
continue;
(*descs)[n++] = pango_font_description_copy(pfd);
}
*n_descs = n;
*descs = g_realloc(*descs, n * sizeof(PangoFontDescription *));
}
struct famlist {
gchar **families;
int last_added;
};
static void
add_entry(gpointer key, gpointer value, gpointer data)
{
struct famlist *fl = data;
fl->families[fl->last_added++] = g_strdup(key);
}
static void
pango_fb_font_map_list_families(PangoFontMap *fontmap,
gchar ***families,
int *n_families)
{
PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap;
int i;
GHashTable *thash = g_hash_table_new(g_str_hash, g_str_equal);
struct famlist stickittome;
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);
}
*n_families = g_hash_table_size(thash);
*families = g_new(gchar *, *n_families);
stickittome.families = *families;
stickittome.last_added = 0;
g_hash_table_foreach(thash, add_entry, &stickittome);
g_hash_table_destroy(thash);
}
static PangoFontMap *
pango_fb_font_map(void)
{
return g_object_new(pango_fb_font_map_get_type(), NULL);
}
PangoMap *
pango_fb_get_shaper_map (const char *lang)
{
static guint engine_type_id = 0;
static guint render_type_id = 0;
if (engine_type_id == 0)
{
engine_type_id = g_quark_try_string(PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_try_string(PANGO_RENDER_TYPE_FB);
}
if (engine_type_id == 0)
{
engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE);
render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_FB);
}
return pango_find_map (lang, engine_type_id, render_type_id);
}
/*************** Font impl *****************/
#define PANGO_FB_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FB_FONT, PangoFBFontClass))
#define PANGO_FB_IS_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FB_FONT))
#define PANGO_FB_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FB_FONT))
#define PANGO_FB_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FB_FONT, PangoFBFontClass))
typedef struct _PangoFBFontClass PangoFBFontClass;
typedef struct _PangoFBMetricsInfo PangoFBMetricsInfo;
typedef struct _PangoFBContextInfo PangoFBContextInfo;
struct _PangoFBMetricsInfo
{
const char *lang;
PangoFontMetrics metrics;
};
struct _PangoFBContextInfo
{
};
struct _PangoFBFontClass
{
PangoFontClass parent_class;
};
static void pango_fb_font_class_init (PangoFBFontClass *class);
static void pango_fb_font_init (PangoFBFont *font);
static void pango_fb_font_finalize (GObject *object);
static PangoFontDescription *pango_fb_font_describe (PangoFont *font);
static PangoCoverage * pango_fb_font_get_coverage (PangoFont *font,
const char *lang);
static PangoEngineShape * pango_fb_font_find_shaper (PangoFont *font,
const char *lang,
guint32 ch);
static void pango_fb_font_get_glyph_extents (PangoFont *font,
PangoGlyph glyph,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
static void pango_fb_font_get_metrics (PangoFont *font,
const gchar *lang,
PangoFontMetrics *metrics);
GType
pango_fb_font_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (PangoFBFontClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) pango_fb_font_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (PangoFBFont),
0, /* n_preallocs */
(GInstanceInitFunc) pango_fb_font_init,
};
object_type = g_type_register_static (PANGO_TYPE_FONT,
"PangoFBFont",
&object_info);
}
return object_type;
}
static void
pango_fb_font_init (PangoFBFont *font)
{
font->desc.size = -1;
font->extents = g_hash_table_new(NULL, NULL);
}
static gboolean
g_free_2(gpointer key, gpointer value, gpointer data)
{
g_free(value);
return TRUE;
}
static void
pango_fb_font_clear_extent_cache(PangoFBFont *fbf)
{
g_hash_table_foreach_remove(fbf->extents, g_free_2, NULL);
}
static void pango_fb_font_finalize (GObject *object)
{
PangoFBFont *fbf = PANGO_FB_FONT(object);
/* XXX FIXME g_hash_table_remove(ourfontmap, &fbf->desc); */
pango_coverage_unref(fbf->coverage);
g_free(fbf->desc.family_name);
pango_fb_font_clear_extent_cache(fbf);
g_hash_table_destroy(fbf->extents);
}
static void
pango_fb_font_class_init (PangoFBFontClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
PangoFontClass *font_class = PANGO_FONT_CLASS (class);
object_class->finalize = pango_fb_font_finalize;
font_class->describe = pango_fb_font_describe;
font_class->get_coverage = pango_fb_font_get_coverage;
font_class->find_shaper = pango_fb_font_find_shaper;
font_class->get_glyph_extents = pango_fb_font_get_glyph_extents;
font_class->get_metrics = pango_fb_font_get_metrics;
}
static PangoFontDescription *
pango_fb_font_describe(PangoFont *font)
{
return pango_font_description_copy(&PANGO_FB_FONT(font)->desc);
}
static void
free_coverages_foreach (gpointer key,
gpointer value,
gpointer data)
{
pango_coverage_unref (value);
}
static PangoCoverage *
pango_fb_font_get_coverage (PangoFont *font,
const char *lang)
{
int i, n;
PangoCoverage *retval;
PangoMap *shape_map;
GHashTable *coverage_hash;
if(PANGO_FB_FONT(font)->coverage)
return pango_coverage_ref(PANGO_FB_FONT(font)->coverage);
shape_map = pango_fb_get_shaper_map(lang);
coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
retval = pango_coverage_new();
n = MIN(65536,PANGO_FB_FONT(font)->ftf->num_glyphs);
for(i = 0; i < n; i++)
{
PangoCoverageLevel font_level;
PangoMapEntry *map_entry;
map_entry = pango_map_get_entry (shape_map, i);
if (map_entry->info)
{
PangoCoverage *coverage;
coverage = g_hash_table_lookup (coverage_hash, map_entry->info->id);
if (!coverage)
{
PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, i);
coverage = engine->get_coverage (font, lang);
g_hash_table_insert (coverage_hash, map_entry->info->id, coverage);
}
font_level = pango_coverage_get (coverage, i);
if (font_level == PANGO_COVERAGE_EXACT && !map_entry->is_exact)
font_level = PANGO_COVERAGE_APPROXIMATE;
if (font_level != PANGO_COVERAGE_NONE)
pango_coverage_set (retval, i, font_level);
}
}
g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL);
g_hash_table_destroy (coverage_hash);
PANGO_FB_FONT(font)->coverage = pango_coverage_ref(retval);
return retval;
}
static PangoEngineShape *
pango_fb_font_find_shaper (PangoFont *font,
const char *lang,
guint32 ch)
{
PangoMap *shape_map = NULL;
shape_map = pango_fb_get_shaper_map (lang);
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)
{
PangoFBFont *fbf = (PangoFBFont *)font;
if(PANGO_FB_FONT(font)->desc.size != GPOINTER_TO_UINT(fbf->ftf->generic.data))
{
fbf->ftf->generic.data = GUINT_TO_POINTER(PANGO_FB_FONT(font)->desc.size);
FT_Set_Char_Size(fbf->ftf, 0, (PANGO_FB_FONT(font)->desc.size << 6)/PANGO_SCALE, 72, 72);
}
}
static void
pango_fb_font_get_glyph_extents (PangoFont *font,
PangoGlyph glyph,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
{
FT_Face ftf;
PangoFBFont *fbf;
PangoRectangle *my_extents, *my_logical_rect, *my_ink_rect;
FT_GlyphSlot gs;
fbf = PANGO_FB_FONT(font);
pango_fb_font_set_size(font);
my_extents = g_hash_table_lookup(fbf->extents, GUINT_TO_POINTER(glyph));
if(my_extents)
goto out;
if(!strcmp(fbf->desc.family_name, "Bitstream Charter"))
G_BREAKPOINT();
ftf = fbf->ftf;
if(FT_Load_Glyph(ftf, glyph, FT_LOAD_DEFAULT))