Commit e275f779 authored by Alexander Larsson's avatar Alexander Larsson Committed by Alexander Larsson

Define EMULATE_GDKFONT. Add extra pango_font stuff to GfkFontPrivate.

2001-01-19    <alexl@redhat.com>

	* gdk/linux-fb/gdkprivate-fb.h:
	Define EMULATE_GDKFONT.
	Add extra pango_font stuff to GfkFontPrivate.

	* gdk/linux-fb/gdkdrawable-fb2.c:
	* gdk/linux-fb/gdkfont-fb.c:
	If EMULATE_GDKFONT defined, implement a slow lame GdkFont
	emulation using PangoFont.
parent ed420445
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
2001-01-19 <alexl@redhat.com>
* gdk/linux-fb/gdkprivate-fb.h:
Define EMULATE_GDKFONT.
Add extra pango_font stuff to GfkFontPrivate.
* gdk/linux-fb/gdkdrawable-fb2.c:
* gdk/linux-fb/gdkfont-fb.c:
If EMULATE_GDKFONT defined, implement a slow lame GdkFont
emulation using PangoFont.
2001-01-17 Havoc Pennington <hp@pobox.com>
* gtk/gtkprogressbar.c, gtk/gtkprogressbar.h: Add "getters" for
......
......@@ -792,9 +792,103 @@ gdk_fb_draw_drawable (GdkDrawable *drawable,
gdk_fb_draw_drawable_2 (drawable, gc, src_impl , xsrc, ysrc, xdest, ydest, width, height, TRUE, TRUE);
}
#ifdef EMULATE_GDKFONT
static void
gdk_fb_draw_text(GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *text,
gint text_length)
{
GdkFontPrivateFB *private;
guchar *utf8, *utf8_end;
PangoGlyphString *glyphs = pango_glyph_string_new ();
PangoEngineShape *shaper, *last_shaper;
PangoAnalysis analysis;
guchar *p, *start;
gint x_offset;
int i;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
private = (GdkFontPrivateFB*) font;
utf8 = alloca (text_length*2);
/* Convert latin-1 to utf8 */
p = utf8;
for (i=0;i<text_length;i++)
{
if (text[i]==0)
*p++ = 1; /* Hack to handle embedded nulls */
else
{
if(((guchar)text[i])<128)
*p++ = text[i];
else
{
*p++ = ((((guchar)text[i])>>6) & 0x3f) | 0xC0;
*p++ = (((guchar)text[i]) & 0x3f) | 0x80;
}
}
}
utf8_end = p;
last_shaper = NULL;
shaper = NULL;
x_offset = 0;
p = start = utf8;
while (p < utf8_end)
{
gunichar wc = g_utf8_get_char (p);
p = g_utf8_next_char (p);
shaper = pango_font_find_shaper (private->pango_font, "fr", wc);
if (shaper != last_shaper)
{
analysis.shape_engine = shaper;
analysis.lang_engine = NULL;
analysis.font = private->pango_font;
analysis.level = 0;
pango_shape (start, p - start, &analysis, glyphs);
gdk_fb_draw_glyphs (drawable, gc, private->pango_font,
x + PANGO_PIXELS (x_offset), y,
glyphs);
for (i = 0; i < glyphs->num_glyphs; i++)
x_offset += glyphs->glyphs[i].geometry.width;
start = p;
}
last_shaper = shaper;
}
if (p > start)
{
analysis.shape_engine = shaper;
analysis.lang_engine = NULL;
analysis.font = private->pango_font;
analysis.level = 0;
pango_shape (start, p - start, &analysis, glyphs);
gdk_fb_draw_glyphs (drawable, gc, private->pango_font,
x + PANGO_PIXELS (x_offset), y,
glyphs);
}
pango_glyph_string_free (glyphs);
return;
}
#else
static void
gdk_fb_draw_text(GdkDrawable *drawable,
GdkFont *font,
......@@ -806,6 +900,7 @@ gdk_fb_draw_text(GdkDrawable *drawable,
{
g_warning ("gdk_fb_draw_text NYI");
}
#endif
static void
gdk_fb_draw_text_wc (GdkDrawable *drawable,
......
......@@ -35,73 +35,36 @@
#include <freetype/freetype.h>
#if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2
#error "We need Freetype 2.0 (beta?)"
#error "We need Freetype 2.0"
#endif
static GdkFont *
gdk_fb_bogus_font (gint height)
{
GdkFont *font;
GdkFontPrivateFB *private;
private = g_new0 (GdkFontPrivateFB, 1);
font = (GdkFont *)private;
font->type = GDK_FONT_FONT;
font->ascent = height*3/4;
font->descent = height/4;
private->size = height;
private->base.ref_count = 1;
return font;
}
GdkFont*
gdk_font_from_description (PangoFontDescription *font_desc)
{
g_return_val_if_fail (font_desc, NULL);
return gdk_fb_bogus_font (PANGO_PIXELS(font_desc->size));
}
/* ********************* */
#if 0
#ifdef EMULATE_GDKFONT
static GHashTable *font_name_hash = NULL;
static GHashTable *fontset_name_hash = NULL;
static void
gdk_font_hash_insert (GdkFontType type, GdkFont *font, const gchar *font_name)
gdk_font_hash_insert (GdkFontType type, GdkFont *font)
{
GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
GHashTable **hashp = (type == GDK_FONT_FONT) ?
&font_name_hash : &fontset_name_hash;
if (!*hashp)
*hashp = g_hash_table_new (g_str_hash, g_str_equal);
private->names = g_slist_prepend (private->names, g_strdup (font_name));
g_hash_table_insert (*hashp, private->names->data, font);
g_hash_table_insert (*hashp, private->name, font);
}
static void
gdk_font_hash_remove (GdkFontType type, GdkFont *font)
{
GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
GSList *tmp_list;
GHashTable *hash = (type == GDK_FONT_FONT) ?
font_name_hash : fontset_name_hash;
tmp_list = private->names;
while (tmp_list)
{
g_hash_table_remove (hash, tmp_list->data);
g_free (tmp_list->data);
tmp_list = tmp_list->next;
}
g_slist_free (private->names);
private->names = NULL;
g_hash_table_remove (hash, private->name);
}
static GdkFont *
......@@ -123,50 +86,148 @@ gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
}
}
GdkFont*
gdk_font_from_description (PangoFontDescription *desc)
{
GdkFont *font;
GdkFontPrivateFB *private;
PangoFont *pango_font;
PangoContext *context;
PangoFontMetrics metrics;
gchar *lang;
g_return_val_if_fail (desc, NULL);
private = g_new0 (GdkFontPrivateFB, 1);
private->base.ref_count = 1;
private->name = NULL;
font = (GdkFont*) private;
font->type = GDK_FONT_FONT;
context = gdk_pango_context_get ();
pango_font = pango_context_load_font (context, desc);
if (!pango_font)
{
g_free (desc->family_name);
desc->family_name = g_strdup ("sans");
pango_font = pango_context_load_font (context, desc);
if (!pango_font)
{
desc->style = PANGO_STYLE_NORMAL;
desc->weight = PANGO_WEIGHT_NORMAL;
desc->variant = PANGO_VARIANT_NORMAL;
desc->stretch = PANGO_STRETCH_NORMAL;
pango_font = pango_context_load_font (context, desc);
}
}
g_assert (pango_font != NULL);
if (pango_font == NULL)
return NULL;
metrics.ascent = 0;
metrics.descent = 0;
lang = pango_context_get_lang (context);
pango_font_get_metrics (pango_font, "fr", &metrics);
private->pango_font = pango_font;
g_free (lang);
g_object_unref (G_OBJECT (context));
font->ascent = PANGO_PIXELS (metrics.ascent);
font->descent = PANGO_PIXELS (metrics.descent);
g_assert ((font->ascent > 0) || (font->descent > 0));
return font;
}
GdkFont*
gdk_font_load (const gchar *font_name)
{
GdkFont *font;
GdkFontPrivateFB *private;
PangoFontDescription desc;
gchar **pieces;
g_return_val_if_fail (font_name != NULL, NULL);
font = gdk_font_hash_lookup (GDK_FONT_FONTSET, font_name);
font = gdk_font_hash_lookup (GDK_FONT_FONT, font_name);
if (font)
return font;
{
char **pieces;
BBox bb;
private = g_new0 (GdkFontPrivateFB, 1);
private->base.ref_count = 1;
private->names = NULL;
pieces = g_strsplit(font_name, "-", 2);
if(pieces[1])
{
private->size = atof(pieces[1]);
private->t1_font_id = T1_AddFont(pieces[0]);
}
else
private->t1_font_id = T1_AddFont((char *)font_name);
g_strfreev(pieces);
/* Default values */
desc.family_name = NULL;
desc.style = PANGO_STYLE_NORMAL;
desc.weight = PANGO_WEIGHT_NORMAL;
desc.variant = PANGO_VARIANT_NORMAL;
desc.stretch = PANGO_STRETCH_NORMAL;
desc.size = 0;
pieces = g_strsplit(font_name, "-", 8);
T1_LoadFont(private->t1_font_id);
CreateNewFontSize(private->t1_font_id, private->size, FALSE);
do {
if (!pieces[0])
break;
if (!pieces[1])
break;
if (!pieces[2])
break;
font = (GdkFont*) private;
font->type = GDK_FONT_FONTSET;
if (strcmp (pieces[2], "*")!=0)
desc.family_name = g_strdup (pieces[2]);
if (!pieces[3])
break;
if (strcmp (pieces[3], "light")==0)
desc.weight = PANGO_WEIGHT_LIGHT;
if (strcmp (pieces[3], "medium")==0)
desc.weight = PANGO_WEIGHT_NORMAL;
if (strcmp (pieces[3], "bold")==0)
desc.weight = PANGO_WEIGHT_BOLD;
if (!pieces[4])
break;
if (strcmp (pieces[4], "r")==0)
desc.style = PANGO_STYLE_NORMAL;
if (strcmp (pieces[4], "i")==0)
desc.style = PANGO_STYLE_ITALIC;
if (strcmp (pieces[4], "o")==0)
desc.style = PANGO_STYLE_OBLIQUE;
if (!pieces[5])
break;
if (!pieces[6])
break;
if (!pieces[7])
break;
bb = T1_GetFontBBox(private->t1_font_id);
if (strcmp (pieces[7], "*")!=0)
desc.size = atoi (pieces[7]) * PANGO_SCALE;
if (desc.size == 0)
desc.size = 12 * PANGO_SCALE;
} while (0);
font = gdk_font_from_description (&desc);
private = (GdkFontPrivateFB*) font;
private->name = g_strdup (font_name);
font->ascent = ((double)bb.ury) / 1000.0 * private->size;
font->descent = ((double)bb.lly) / -1000.0 * private->size;
}
gdk_font_hash_insert (GDK_FONT_FONT, font);
gdk_font_hash_insert (GDK_FONT_FONTSET, font, font_name);
g_strfreev(pieces);
g_free (desc.family_name);
return font;
}
......@@ -175,7 +236,217 @@ gdk_fontset_load (const gchar *fontset_name)
{
return gdk_font_load(fontset_name);
}
#endif
void
_gdk_font_destroy (GdkFont *font)
{
GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
gdk_font_hash_remove (font->type, font);
g_object_unref (G_OBJECT (private->pango_font));
g_free (private->name);
g_free (font);
}
gint
_gdk_font_strlen (GdkFont *font,
const gchar *str)
{
GdkFontPrivateFB *font_private;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (str != NULL, -1);
font_private = (GdkFontPrivateFB*) font;
return strlen (str);
}
gint
gdk_text_width (GdkFont *font,
const gchar *text,
gint text_length)
{
gint width = -1;
gdk_text_extents (font, text, text_length, NULL, NULL, &width, NULL, NULL);
return width;
}
/* Assumes text is in Latin-1 for performance reasons.
If you need another encoding, use pangofont */
void
gdk_text_extents (GdkFont *font,
const gchar *text,
gint text_length,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
GdkFontPrivateFB *private;
guchar *utf8, *utf8_end;
PangoGlyphString *glyphs = pango_glyph_string_new ();
PangoEngineShape *shaper, *last_shaper;
PangoAnalysis analysis;
guchar *p, *start;
int i;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
private = (GdkFontPrivateFB*) font;
if(ascent)
*ascent = 0;
if(descent)
*descent = 0;
if(width)
*width = 0;
if(lbearing)
*lbearing = 0;
if(rbearing)
*rbearing = 0;
utf8 = alloca (text_length*2);
/* Convert latin-1 to utf8 */
p = utf8;
for (i=0;i<text_length;i++)
{
if (text[i]==0)
*p++ = 1; /* Hack to handle embedded nulls */
else
{
if(((guchar)text[i])<128)
*p++ = text[i];
else
{
*p++ = ((((guchar)text[i])>>6) & 0x3f) | 0xC0;
*p++ = (((guchar)text[i]) & 0x3f) | 0x80;
}
}
}
utf8_end = p;
last_shaper = NULL;
shaper = NULL;
p = start = utf8;
while (p < utf8_end)
{
gunichar wc = g_utf8_get_char (p);
p = g_utf8_next_char (p);
shaper = pango_font_find_shaper (private->pango_font, "fr", wc);
if (shaper != last_shaper)
{
analysis.shape_engine = shaper;
analysis.lang_engine = NULL;
analysis.font = private->pango_font;
analysis.level = 0;
pango_shape (start, p - start, &analysis, glyphs);
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoRectangle ink_rect;
PangoGlyphGeometry *geometry = &glyphs->glyphs[i].geometry;
pango_font_get_glyph_extents (private->pango_font, glyphs->glyphs[i].glyph,
&ink_rect, NULL);
if(ascent)
*ascent = MAX (*ascent, ink_rect.y);
if(descent)
*descent = MAX (*descent, ink_rect.height - ink_rect.y);
if(width)
*width += geometry->width;
if(lbearing)
*lbearing = 0;
if(rbearing)
*rbearing = 0;
}
start = p;
}
last_shaper = shaper;
}
if (p > start)
{
analysis.shape_engine = shaper;
analysis.lang_engine = NULL;
analysis.font = private->pango_font;
analysis.level = 0;
pango_shape (start, p - start, &analysis, glyphs);
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoRectangle ink_rect;
PangoGlyphGeometry *geometry = &glyphs->glyphs[i].geometry;
pango_font_get_glyph_extents (private->pango_font, glyphs->glyphs[i].glyph,
&ink_rect, NULL);
if(ascent)
*ascent = MAX (*ascent, ink_rect.y);
if(descent)
*descent = MAX (*descent, ink_rect.height - ink_rect.y);
if(width)
*width += geometry->width;
if(lbearing)
*lbearing = 0;
if(rbearing)
*rbearing = 0;
}
}
pango_glyph_string_free (glyphs);
if(ascent)
*ascent = PANGO_PIXELS (*ascent);
if(descent)
*descent = PANGO_PIXELS(*descent);
if(width)
*width = PANGO_PIXELS (*width);
if(lbearing)
*lbearing = PANGO_PIXELS (*lbearing);
if(rbearing)
*rbearing = PANGO_PIXELS (*rbearing);
}
#else
/* Don't emulate GdkFont */
static GdkFont *
gdk_fb_bogus_font (gint height)
{
GdkFont *font;
GdkFontPrivateFB *private;
private = g_new0 (GdkFontPrivateFB, 1);
font = (GdkFont *)private;
font->type = GDK_FONT_FONT;
font->ascent = height*3/4;
font->descent = height/4;
private->size = height;
private->base.ref_count = 1;
return font;
}
GdkFont*
gdk_font_from_description (PangoFontDescription *font_desc)
{
g_return_val_if_fail (font_desc, NULL);
return gdk_fb_bogus_font (PANGO_PIXELS (font_desc->size));
}
GdkFont*