Uh? What happed? My cvs checkin got broken pipe..
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
#include "mi.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <pango/pangoft2.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
|
||||
#ifndef g_alloca
|
||||
@ -879,10 +880,6 @@ gdk_fb_drawable_clear (GdkDrawable *d)
|
||||
_gdk_windowing_window_clear_area (d, 0, 0, GDK_DRAWABLE_IMPL_FBDATA (d)->width, GDK_DRAWABLE_IMPL_FBDATA (d)->height);
|
||||
}
|
||||
|
||||
extern FT_Library gdk_fb_ft_lib;
|
||||
|
||||
extern void pango_fb_font_set_size(PangoFont *font);
|
||||
|
||||
static void
|
||||
gdk_fb_draw_glyphs (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
@ -891,9 +888,14 @@ gdk_fb_draw_glyphs (GdkDrawable *drawable,
|
||||
gint y,
|
||||
PangoGlyphString *glyphs)
|
||||
{
|
||||
int i;
|
||||
int xpos;
|
||||
GdkFBDrawingContext fbdc;
|
||||
FT_Bitmap bitmap;
|
||||
GdkPixmapFBData pixmap;
|
||||
PangoFT2Subfont subfont_index;
|
||||
PangoGlyphInfo *gi;
|
||||
FT_Face face;
|
||||
FT_UInt glyph_index;
|
||||
int i, xpos;
|
||||
|
||||
g_return_if_fail (font);
|
||||
|
||||
@ -901,20 +903,39 @@ gdk_fb_draw_glyphs (GdkDrawable *drawable,
|
||||
|
||||
/* Fake its existence as a pixmap */
|
||||
|
||||
pango_fb_font_set_size (font);
|
||||
|
||||
for (i = xpos = 0; i < glyphs->num_glyphs; i++)
|
||||
pixmap.drawable_data.abs_x = 0;
|
||||
pixmap.drawable_data.abs_y = 0;
|
||||
pixmap.drawable_data.depth = 78;
|
||||
|
||||
gi = glyphs->glyphs;
|
||||
for (i = 0, xpos = 0; i < glyphs->num_glyphs; i++, gi++)
|
||||
{
|
||||
PangoFBGlyphInfo *pgi;
|
||||
if (gi->glyph)
|
||||
{
|
||||
glyph_index = PANGO_FT2_GLYPH_INDEX (gi->glyph);
|
||||
subfont_index = PANGO_FT2_GLYPH_SUBFONT (gi->glyph);
|
||||
face = pango_ft2_get_face (font, subfont_index);
|
||||
|
||||
pgi = pango_fb_font_get_glyph_info (font, glyphs->glyphs[i].glyph);
|
||||
|
||||
gdk_fb_draw_drawable_3 (drawable, gc, (GdkPixmap *)&pgi->fbd,
|
||||
&fbdc,
|
||||
0, 0,
|
||||
x + PANGO_PIXELS (xpos) + pgi->left , y - pgi->top + 1,
|
||||
pgi->fbd.drawable_data.width, pgi->fbd.drawable_data.height);
|
||||
if (face)
|
||||
{
|
||||
/* Draw glyph */
|
||||
FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT);
|
||||
if (face->glyph->format != ft_glyph_format_bitmap)
|
||||
FT_Render_Glyph (face->glyph, ft_render_mode_normal);
|
||||
|
||||
pixmap.drawable_data.mem = face->glyph->bitmap.buffer;
|
||||
pixmap.drawable_data.rowstride = face->glyph->bitmap.pitch;
|
||||
pixmap.drawable_data.width = face->glyph->bitmap.width;
|
||||
pixmap.drawable_data.height = face->glyph->bitmap.rows;
|
||||
|
||||
gdk_fb_draw_drawable_3 (drawable, gc, (GdkPixmap *)&pixmap,
|
||||
&fbdc,
|
||||
0, 0,
|
||||
x + PANGO_PIXELS (xpos) + face->glyph->bitmap_left,
|
||||
y - face->glyph->bitmap_top + 1,
|
||||
face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||
}
|
||||
}
|
||||
xpos += glyphs->glyphs[i].geometry.width;
|
||||
}
|
||||
|
||||
|
||||
@ -22,4 +22,20 @@ extern const char *gdk_progclass;
|
||||
|
||||
extern GdkAtom gdk_selection_property;
|
||||
|
||||
/* FB specific functions: */
|
||||
|
||||
typedef gboolean (*GdkWindowChildChanged) (GdkWindow *window,
|
||||
gint x, gint y,
|
||||
gint width, gint height,
|
||||
gpointer user_data);
|
||||
typedef void (*GdkWindowChildGetPos) (GdkWindow *window,
|
||||
gint *x, gint *y,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean _gdk_window_get_decorations (GdkWindow *window,
|
||||
GdkWMDecoration *decorations);
|
||||
void _gdk_window_set_child_handler (GdkWindow *window,
|
||||
GdkWindowChildChanged changed,
|
||||
GdkWindowChildGetPos get_pos,
|
||||
gpointer user_data);
|
||||
#endif /* GDKFB_H */
|
||||
|
||||
@ -634,8 +634,6 @@ _gdk_windowing_init_check (int argc, char **argv)
|
||||
if (!gdk_display)
|
||||
return FALSE;
|
||||
|
||||
gdk_fb_font_init ();
|
||||
|
||||
if (!gdk_fb_keyboard_open ())
|
||||
{
|
||||
g_warning ("Failed to initialize keyboard");
|
||||
@ -1009,8 +1007,6 @@ gdk_windowing_exit (void)
|
||||
|
||||
gdk_fb_keyboard_close ();
|
||||
|
||||
gdk_fb_font_fini ();
|
||||
|
||||
gdk_fb_display_destroy (gdk_display);
|
||||
|
||||
gdk_display = NULL;
|
||||
|
||||
@ -1,901 +1,11 @@
|
||||
#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 <pango/pangoft2.h>
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
#include <freetype/ftglyph.h>
|
||||
|
||||
#if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2
|
||||
#error "We need Freetype 2.0"
|
||||
#endif
|
||||
|
||||
#define PANGO_RENDER_TYPE_FB "PangoRenderTypeFB"
|
||||
|
||||
#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
|
||||
#define PANGO_PIXELS_26_6(d) \
|
||||
(((d) >= 0) ? \
|
||||
((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \
|
||||
((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
|
||||
#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
|
||||
|
||||
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;
|
||||
|
||||
#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_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL},
|
||||
{
|
||||
{"Arial", PANGO_STYLE_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL},
|
||||
{"URW Gothic L", PANGO_STYLE_ITALIC, 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_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL},
|
||||
{
|
||||
{"Arial", PANGO_STYLE_ITALIC, 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_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL},
|
||||
{
|
||||
{"Times New Roman", PANGO_STYLE_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL},
|
||||
{"URW Bookman L", PANGO_STYLE_ITALIC, 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_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL},
|
||||
{
|
||||
{"Times New Roman", PANGO_STYLE_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL},
|
||||
{"URW Bookman L", PANGO_STYLE_ITALIC, 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_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL},
|
||||
{
|
||||
{"Courier New", PANGO_STYLE_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_NORMAL, PANGO_STRETCH_NORMAL},
|
||||
{"Courier", PANGO_STYLE_ITALIC, 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_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL},
|
||||
{
|
||||
{"Courier New", PANGO_STYLE_ITALIC, PANGO_VARIANT_NORMAL, PANGO_WEIGHT_BOLD, PANGO_STRETCH_NORMAL},
|
||||
{"Courier", PANGO_STYLE_ITALIC, 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);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_fb_font_fini (void)
|
||||
{
|
||||
FT_Done_FreeType (gdk_fb_ft_lib);
|
||||
}
|
||||
|
||||
void pango_fb_font_set_size (PangoFont *font);
|
||||
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,
|
||||
0);
|
||||
}
|
||||
|
||||
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_lookup_descr (PangoFontMap *fontmap,
|
||||
const PangoFontDescription *desc,
|
||||
const PangoFontDescription *save_as)
|
||||
{
|
||||
PangoFBFontMap *fbfm = (PangoFBFontMap *)fontmap;
|
||||
PangoFBFont *retval;
|
||||
PangoFBFontListing *fl = NULL;
|
||||
int i;
|
||||
|
||||
retval = g_hash_table_lookup (fbfm->all_fonts, desc);
|
||||
|
||||
if (retval)
|
||||
{
|
||||
g_object_ref (G_OBJECT(retval));
|
||||
return (PangoFont *)retval;
|
||||
}
|
||||
|
||||
for (i = 0; i < fbfm->all_descs->len; i++)
|
||||
{
|
||||
fl = g_ptr_array_index (fbfm->all_descs, i);
|
||||
|
||||
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 = *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
|
||||
signals in gobject */
|
||||
|
||||
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
|
||||
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)
|
||||
break; /* error opening */
|
||||
|
||||
n = ftf->num_faces;
|
||||
|
||||
if (!ftf->family_name || !ftf->style_name)
|
||||
{
|
||||
g_warning ("No family/style on %s", buf);
|
||||
FT_Done_Face (ftf);
|
||||
break;
|
||||
}
|
||||
|
||||
pfd = g_new0 (PangoFBFontListing, 1);
|
||||
/* Now add the item */
|
||||
if (ftf->family_name[0] == '/')
|
||||
pfd->desc.family_name = g_strdup (ftf->family_name+1);
|
||||
else
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir (dirh);
|
||||
}
|
||||
|
||||
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",
|
||||
GDK_DATA_PREFIX "/share/fonts",
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
|
||||
fontmap->all_fonts = g_hash_table_new (pango_font_description_hash, (GEqualFunc)pango_font_description_equal);
|
||||
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 + ALIAS_TABLE_LEN);
|
||||
*n_descs = fbfm->all_descs->len + ALIAS_TABLE_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);
|
||||
}
|
||||
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 *));
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
|
||||
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,
|
||||
0);
|
||||
}
|
||||
|
||||
return object_type;
|
||||
}
|
||||
|
||||
static void
|
||||
pango_fb_font_init (PangoFBFont *font)
|
||||
{
|
||||
font->desc.size = -1;
|
||||
font->glyph_info = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_free_2(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
PangoFBGlyphInfo *pgi = value;
|
||||
g_free (pgi->fbd.drawable_data.mem);
|
||||
g_free (value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pango_fb_font_clear_extent_cache(PangoFBFont *fbf)
|
||||
{
|
||||
g_hash_table_foreach_remove (fbf->glyph_info, g_free_2, NULL);
|
||||
}
|
||||
|
||||
PangoFBGlyphInfo *
|
||||
pango_fb_font_get_glyph_info (PangoFont *font, PangoGlyph glyph)
|
||||
{
|
||||
PangoFBGlyphInfo *pgi;
|
||||
PangoFBFont *fbf = PANGO_FB_FONT (font);
|
||||
FT_Bitmap *renderme;
|
||||
FT_GlyphSlot g;
|
||||
PangoRectangle *my_logical_rect, *my_ink_rect;
|
||||
FT_Face ftf;
|
||||
FT_Error ec;
|
||||
|
||||
ftf = fbf->ftf;
|
||||
|
||||
pango_fb_font_set_size (font);
|
||||
|
||||
pgi = g_hash_table_lookup (fbf->glyph_info, GUINT_TO_POINTER (glyph));
|
||||
if (pgi)
|
||||
return pgi;
|
||||
|
||||
pgi = g_new0 (PangoFBGlyphInfo, 1);
|
||||
|
||||
ec = FT_Load_Glyph (ftf, glyph, FT_LOAD_DEFAULT);
|
||||
|
||||
g = ftf->glyph;
|
||||
|
||||
if (g->format != ft_glyph_format_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;
|
||||
pgi->fbd.drawable_data.width = pgi->fbd.drawable_data.lim_x = renderme->width;
|
||||
pgi->fbd.drawable_data.height = pgi->fbd.drawable_data.lim_y = renderme->rows;
|
||||
|
||||
switch (renderme->pixel_mode)
|
||||
{
|
||||
case ft_pixel_mode_mono:
|
||||
pgi->fbd.drawable_data.depth = 1;
|
||||
break;
|
||||
case ft_pixel_mode_grays:
|
||||
pgi->fbd.drawable_data.depth = 78;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
my_ink_rect = &pgi->extents[0];
|
||||
my_logical_rect = &pgi->extents[1];
|
||||
|
||||
my_ink_rect->x = PANGO_UNITS_26_6 (g->metrics.horiBearingX);
|
||||
my_ink_rect->width = PANGO_UNITS_26_6 (g->metrics.width);
|
||||
my_ink_rect->y = -PANGO_UNITS_26_6 (g->metrics.horiBearingY);
|
||||
my_ink_rect->height = PANGO_UNITS_26_6 (g->metrics.height);
|
||||
|
||||
my_logical_rect->x = 0;
|
||||
my_logical_rect->width = PANGO_UNITS_26_6 (g->metrics.horiAdvance);
|
||||
my_logical_rect->y = -PANGO_UNITS_26_6 (ftf->size->metrics.ascender + 64);
|
||||
my_logical_rect->height = PANGO_UNITS_26_6 (ftf->size->metrics.height + 128);
|
||||
|
||||
g_hash_table_insert (fbf->glyph_info, GUINT_TO_POINTER(glyph), pgi);
|
||||
|
||||
return pgi;
|
||||
}
|
||||
|
||||
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->glyph_info);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
pango_fb_font_set_size (PangoFont *font)
|
||||
{
|
||||
PangoFBFont *fbf = (PangoFBFont *)font;
|
||||
gint height;
|
||||
|
||||
if (PANGO_FB_FONT (font)->desc.size != GPOINTER_TO_UINT (fbf->ftf->generic.data))
|
||||
{
|
||||
height = PANGO_FB_FONT (font)->desc.size;
|
||||
fbf->ftf->generic.data = GUINT_TO_POINTER (height);
|
||||
FT_Set_Char_Size (fbf->ftf, 0, PANGO_PIXELS_26_6 (height), 72, 72);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pango_fb_font_get_glyph_extents (PangoFont *font,
|
||||
PangoGlyph glyph,
|
||||
PangoRectangle *ink_rect,
|
||||
PangoRectangle *logical_rect)
|
||||
{
|
||||
PangoFBFont *fbf;
|
||||
PangoRectangle *my_extents;
|
||||
PangoFBGlyphInfo *gi;
|
||||
|
||||
fbf = PANGO_FB_FONT (font);
|
||||
|
||||
gi = pango_fb_font_get_glyph_info (font, glyph);
|
||||
my_extents = gi->extents;
|
||||
|
||||
if (ink_rect)
|
||||
*ink_rect = my_extents[0];
|
||||
|
||||
if (logical_rect)
|
||||
*logical_rect = my_extents[1];
|
||||
}
|
||||
|
||||
static void
|
||||
pango_fb_font_get_metrics (PangoFont *font,
|
||||
const gchar *lang,
|
||||
PangoFontMetrics *metrics)
|
||||
{
|
||||
FT_Face ftf;
|
||||
|
||||
ftf = PANGO_FB_FONT (font)->ftf;
|
||||
|
||||
pango_fb_font_set_size (font);
|
||||
|
||||
if (metrics)
|
||||
{
|
||||
metrics->ascent = PANGO_UNITS_26_6 (ftf->size->metrics.ascender);
|
||||
metrics->descent = PANGO_UNITS_26_6 (-ftf->size->metrics.descender);
|
||||
}
|
||||
}
|
||||
|
||||
/* The following array is supposed to contain enough text to tickle all necessary fonts for each
|
||||
* of the languages in the following. Yes, it's pretty lame. Not all of the languages
|
||||
* in the following have sufficient text to excercise all the accents for the language, and
|
||||
* there are obviously many more languages to include as well.
|
||||
*/
|
||||
#if 0
|
||||
LangInfo lang_texts[] = {
|
||||
{ "ar", "Arabic السلام عليكم" },
|
||||
{ "cs", "Czech (česky) Dobrý den" },
|
||||
{ "da", "Danish (Dansk) Hej, Goddag" },
|
||||
{ "el", "Greek (Ελληνικά) Γειά σας" },
|
||||
{ "en", "English Hello" },
|
||||
{ "eo", "Esperanto Saluton" },
|
||||
{ "es", "Spanish (Español) ¡Hola!" },
|
||||
{ "et", "Estonian Tere, Tervist" },
|
||||
{ "fi", "Finnish (Suomi) Hei" },
|
||||
{ "fr", "French (Français)" },
|
||||
{ "de", "German Grüß Gott" },
|
||||
{ "iw", "Hebrew שלום" },
|
||||
{ "il", "Italiano Ciao, Buon giorno" },
|
||||
{ "ja", "Japanese (日本語) こんにちは, コンニチハ" },
|
||||
{ "ko", "Korean (한글) 안녕하세요, 안녕하십니까" },
|
||||
{ "mt", "Maltese Ċaw, Saħħa" },
|
||||
{ "nl", "Nederlands, Vlaams Hallo, Dag" },
|
||||
{ "no", "Norwegian (Norsk) Hei, God dag" },
|
||||
{ "pl", "Polish Dzień dobry, Hej" },
|
||||
{ "ru", "Russian (Русский)" },
|
||||
{ "sk", "Slovak Dobrý deň" },
|
||||
{ "sv", "Swedish (Svenska) Hej, Goddag" },
|
||||
{ "tr", "Turkish (Türkçe) Merhaba" },
|
||||
{ "zh", "Chinese (中文,普通话,汉语)" }
|
||||
};
|
||||
#endif
|
||||
|
||||
/******** misc gdk tie-ins **********/
|
||||
PangoContext *
|
||||
gdk_pango_context_get (void)
|
||||
{
|
||||
PangoContext *retval;
|
||||
static PangoFontMap *font_map = NULL;
|
||||
|
||||
if (!font_map)
|
||||
font_map = pango_fb_font_map ();
|
||||
|
||||
retval = pango_context_new ();
|
||||
|
||||
pango_context_add_font_map (retval, font_map);
|
||||
|
||||
return retval;
|
||||
return pango_ft2_get_context ();
|
||||
}
|
||||
|
||||
@ -158,9 +158,6 @@ typedef struct {
|
||||
int size;
|
||||
} GdkFontPrivateFB;
|
||||
|
||||
void gdk_fb_font_init(void);
|
||||
void gdk_fb_font_fini(void);
|
||||
|
||||
typedef struct {
|
||||
/* Empty */
|
||||
} GdkImagePrivateFB;
|
||||
@ -267,11 +264,9 @@ void gdk_fb_window_move_resize (GdkWindow *window,
|
||||
gint height,
|
||||
gboolean send_expose_events);
|
||||
GdkWindow *gdk_fb_window_find_focus (void);
|
||||
|
||||
|
||||
GdkGC * _gdk_fb_gc_new (GdkDrawable *drawable,
|
||||
GdkGCValues *values,
|
||||
GdkGCValuesMask values_mask);
|
||||
GdkGC * _gdk_fb_gc_new (GdkDrawable *drawable,
|
||||
GdkGCValues *values,
|
||||
GdkGCValuesMask values_mask);
|
||||
|
||||
#define _GDK_FB_GC_DEPTH (1<<31)
|
||||
void _gdk_fb_gc_calc_state (GdkGC *gc,
|
||||
@ -400,31 +395,6 @@ void gdk_fb_mouse_get_info (gint *x,
|
||||
GdkModifierType *mask);
|
||||
|
||||
|
||||
#define PANGO_TYPE_FB_FONT (pango_fb_font_get_type ())
|
||||
#define PANGO_FB_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FB_FONT, PangoFBFont))
|
||||
|
||||
typedef struct _PangoFBFont PangoFBFont;
|
||||
|
||||
struct _PangoFBFont
|
||||
{
|
||||
PangoFont parent;
|
||||
|
||||
FT_Face ftf;
|
||||
PangoFontDescription desc;
|
||||
PangoCoverage *coverage;
|
||||
GHashTable *glyph_info;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
PangoRectangle extents[2];
|
||||
GdkPixmapFBData fbd;
|
||||
int top, left;
|
||||
} PangoFBGlyphInfo;
|
||||
|
||||
GType pango_fb_font_get_type (void) G_GNUC_CONST;
|
||||
PangoFBGlyphInfo *pango_fb_font_get_glyph_info (PangoFont *font,
|
||||
PangoGlyph glyph);
|
||||
|
||||
extern void CM(void); /* Check for general mem corruption */
|
||||
extern void RP(GdkDrawable *drawable); /* Same, for pixmaps */
|
||||
|
||||
|
||||
@ -40,6 +40,14 @@ static gpointer parent_class = NULL;
|
||||
|
||||
static void recompute_drawable (GdkDrawable *drawable);
|
||||
static void gdk_fb_window_raise (GdkWindow *window);
|
||||
static GdkRegion* gdk_window_fb_get_visible_region (GdkDrawable *drawable);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkWindowChildChanged changed;
|
||||
GdkWindowChildGetPos get_pos;
|
||||
gpointer user_data;
|
||||
} GdkWindowChildHandlerData;
|
||||
|
||||
static void
|
||||
g_free_2nd (gpointer a, gpointer b, gpointer data)
|
||||
@ -71,11 +79,15 @@ static void
|
||||
gdk_window_impl_fb_class_init (GdkWindowFBClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
/* GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); */
|
||||
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
object_class->finalize = gdk_window_impl_fb_finalize;
|
||||
|
||||
/* Visible and clip regions are the same */
|
||||
drawable_class->get_clip_region = gdk_window_fb_get_visible_region;
|
||||
drawable_class->get_visible_region = gdk_window_fb_get_visible_region;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -784,6 +796,7 @@ gdk_window_resize (GdkWindow *window,
|
||||
gint height)
|
||||
{
|
||||
GdkWindowObject *private;
|
||||
gint x, y;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
@ -794,7 +807,21 @@ gdk_window_resize (GdkWindow *window,
|
||||
width = 1;
|
||||
if (height < 1)
|
||||
height = 1;
|
||||
gdk_window_move_resize (window, private->x, private->y, width, height);
|
||||
|
||||
x = private->x;
|
||||
y = private->y;
|
||||
|
||||
if (private->parent && (private->parent->window_type != GDK_WINDOW_CHILD))
|
||||
{
|
||||
GdkWindowChildHandlerData *data;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (private->parent), "gdk-window-child-handler");
|
||||
|
||||
if (data)
|
||||
(*data->get_pos) (window, &x, &y, data->user_data);
|
||||
}
|
||||
|
||||
gdk_window_move_resize (window, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -902,6 +929,16 @@ gdk_fb_window_move_resize (GdkWindow *window,
|
||||
|
||||
private = (GdkWindowObject*) window;
|
||||
|
||||
if (private->parent && (private->parent->window_type != GDK_WINDOW_CHILD))
|
||||
{
|
||||
GdkWindowChildHandlerData *data;
|
||||
|
||||
data = g_object_get_data (G_OBJECT (private->parent), "gdk-window-child-handler");
|
||||
|
||||
if (data && (*data->changed) (window, x, y, width, height, data->user_data))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!private->destroyed)
|
||||
{
|
||||
GdkRegion *old_region = NULL;
|
||||
@ -937,7 +974,7 @@ gdk_fb_window_move_resize (GdkWindow *window,
|
||||
gdk_region_offset (region, dx, dy);
|
||||
gdk_region_intersect (region, new_region);
|
||||
|
||||
if (region->numRects)
|
||||
if (region->numRects && ((dx != 0) || (dy != 0)))
|
||||
{
|
||||
GdkFBDrawingContext fbdc;
|
||||
|
||||
@ -1411,6 +1448,28 @@ gdk_window_get_root_origin (GdkWindow *window,
|
||||
gdk_window_get_deskrelative_origin (window, x, y);
|
||||
}
|
||||
|
||||
static GdkRegion*
|
||||
gdk_window_fb_get_visible_region (GdkDrawable *drawable)
|
||||
{
|
||||
GdkDrawableFBData *priv = GDK_DRAWABLE_FBDATA (drawable);
|
||||
GdkRectangle result_rect;
|
||||
GdkRectangle screen_rect;
|
||||
|
||||
result_rect.x = 0;
|
||||
result_rect.y = 0;
|
||||
result_rect.width = priv->width;
|
||||
result_rect.height = priv->height;
|
||||
|
||||
screen_rect.x = -priv->abs_x;
|
||||
screen_rect.y = -priv->abs_y;
|
||||
screen_rect.width = gdk_display->modeinfo.xres;
|
||||
screen_rect.height = gdk_display->modeinfo.yres;
|
||||
|
||||
gdk_rectangle_intersect (&result_rect, &screen_rect, &result_rect);
|
||||
|
||||
return gdk_region_rectangle (&result_rect);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
gdk_window_get_pointer (GdkWindow *window,
|
||||
gint *x,
|
||||
@ -1599,13 +1658,58 @@ gdk_window_set_group (GdkWindow *window,
|
||||
}
|
||||
|
||||
void
|
||||
gdk_window_set_decorations (GdkWindow *window,
|
||||
GdkWMDecoration decorations)
|
||||
_gdk_window_set_child_handler (GdkWindow *window,
|
||||
GdkWindowChildChanged changed,
|
||||
GdkWindowChildGetPos get_pos,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkWindowChildHandlerData *data;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
/* N/A */
|
||||
data = g_new (GdkWindowChildHandlerData, 1);
|
||||
data->changed = changed;
|
||||
data->get_pos = get_pos;
|
||||
data->user_data = user_data;
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "gdk-window-child-handler",
|
||||
data, (GDestroyNotify) g_free);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_window_set_decorations (GdkWindow *window,
|
||||
GdkWMDecoration decorations)
|
||||
{
|
||||
GdkWMDecoration *dec;
|
||||
|
||||
g_return_if_fail (window != NULL);
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
dec = g_new (GdkWMDecoration, 1);
|
||||
*dec = decorations;
|
||||
|
||||
g_object_set_data_full (G_OBJECT (window), "gdk-window-decorations",
|
||||
dec, (GDestroyNotify) g_free);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_window_get_decorations(GdkWindow *window,
|
||||
GdkWMDecoration *decorations)
|
||||
{
|
||||
GdkWMDecoration *dec;
|
||||
|
||||
g_return_val_if_fail (window != NULL, FALSE);
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
|
||||
|
||||
|
||||
dec = g_object_get_data (G_OBJECT (window), "gdk-window-decorations");
|
||||
if (dec)
|
||||
{
|
||||
*decorations = *dec;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user