1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include "gdkprivate-fb.h"
34 #include <pango/pango.h>
36 #include <freetype/freetype.h>
37 #if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2
38 #error "We need Freetype 2.0 (beta?)"
42 gdk_font_from_description (PangoFontDescription *font_desc)
45 GdkFontPrivateFB *private;
47 g_return_val_if_fail (font_desc, NULL);
49 private = g_new0 (GdkFontPrivateFB, 1);
50 font = (GdkFont *)private;
51 private->base.ref_count = 1;
56 /* ********************* */
58 static GHashTable *font_name_hash = NULL;
59 static GHashTable *fontset_name_hash = NULL;
62 gdk_font_hash_insert (GdkFontType type, GdkFont *font, const gchar *font_name)
64 GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
65 GHashTable **hashp = (type == GDK_FONT_FONT) ?
66 &font_name_hash : &fontset_name_hash;
69 *hashp = g_hash_table_new (g_str_hash, g_str_equal);
71 private->names = g_slist_prepend (private->names, g_strdup (font_name));
72 g_hash_table_insert (*hashp, private->names->data, font);
76 gdk_font_hash_remove (GdkFontType type, GdkFont *font)
78 GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
80 GHashTable *hash = (type == GDK_FONT_FONT) ?
81 font_name_hash : fontset_name_hash;
83 tmp_list = private->names;
86 g_hash_table_remove (hash, tmp_list->data);
87 g_free (tmp_list->data);
89 tmp_list = tmp_list->next;
92 g_slist_free (private->names);
93 private->names = NULL;
97 gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
100 GHashTable *hash = (type == GDK_FONT_FONT) ?
101 font_name_hash : fontset_name_hash;
107 result = g_hash_table_lookup (hash, font_name);
109 gdk_font_ref (result);
116 gdk_font_load (const gchar *font_name)
119 GdkFontPrivateFB *private;
121 g_return_val_if_fail (font_name != NULL, NULL);
123 font = gdk_font_hash_lookup (GDK_FONT_FONTSET, font_name);
131 private = g_new0 (GdkFontPrivateFB, 1);
132 private->base.ref_count = 1;
133 private->names = NULL;
135 pieces = g_strsplit(font_name, "-", 2);
138 private->size = atof(pieces[1]);
139 private->t1_font_id = T1_AddFont(pieces[0]);
142 private->t1_font_id = T1_AddFont((char *)font_name);
145 T1_LoadFont(private->t1_font_id);
146 CreateNewFontSize(private->t1_font_id, private->size, FALSE);
148 font = (GdkFont*) private;
149 font->type = GDK_FONT_FONTSET;
151 bb = T1_GetFontBBox(private->t1_font_id);
153 font->ascent = ((double)bb.ury) / 1000.0 * private->size;
154 font->descent = ((double)bb.lly) / -1000.0 * private->size;
157 gdk_font_hash_insert (GDK_FONT_FONTSET, font, font_name);
163 gdk_fontset_load (const gchar *fontset_name)
165 return gdk_font_load(fontset_name);
170 gdk_font_load (const gchar *font_name)
176 _gdk_font_destroy (GdkFont *font)
179 gdk_font_hash_remove (font->type, font);
186 case GDK_FONT_FONTSET:
189 g_error ("unknown font type.");
196 _gdk_font_strlen (GdkFont *font,
199 GdkFontPrivateFB *font_private;
202 g_return_val_if_fail (font != NULL, -1);
203 g_return_val_if_fail (str != NULL, -1);
205 font_private = (GdkFontPrivateFB*) font;
207 if (font->type == GDK_FONT_FONT)
209 guint16 *string_2b = (guint16 *)str;
211 while (*(string_2b++))
214 else if (font->type == GDK_FONT_FONTSET)
216 length = strlen (str);
219 g_error("undefined font type\n");
225 gdk_font_id (const GdkFont *font)
227 const GdkFontPrivateFB *font_private;
229 g_return_val_if_fail (font != NULL, 0);
231 font_private = (const GdkFontPrivateFB*) font;
233 if (font->type == GDK_FONT_FONT)
244 gdk_font_equal (const GdkFont *fonta,
245 const GdkFont *fontb)
247 const GdkFontPrivateFB *privatea;
248 const GdkFontPrivateFB *privateb;
250 g_return_val_if_fail (fonta != NULL, FALSE);
251 g_return_val_if_fail (fontb != NULL, FALSE);
253 privatea = (const GdkFontPrivateFB*) fonta;
254 privateb = (const GdkFontPrivateFB*) fontb;
259 if(privatea->t1_font_id == privateb->t1_font_id
260 && privatea->size == privateb->size)
268 gdk_text_width (GdkFont *font,
273 GdkFontPrivateFB *private;
277 g_return_val_if_fail (font != NULL, -1);
278 g_return_val_if_fail (text != NULL, -1);
280 private = (GdkFontPrivateFB*) font;
285 case GDK_FONT_FONTSET:
286 n = private->size / 1000.0;
287 n *= T1_GetStringWidth(private->t1_font_id, (char *)text, text_length, 0, T1_KERNING);
302 gdk_text_width_wc (GdkFont *font,
303 const GdkWChar *text,
310 realstr = alloca(text_length + 1);
311 for(i = 0; i < text_length; i++)
312 realstr[i] = text[i];
315 return gdk_text_width(font, realstr, text_length);
322 gdk_text_extents (GdkFont *font,
332 GdkFontPrivateFB *private;
335 g_return_if_fail (font != NULL);
336 g_return_if_fail (text != NULL);
338 private = (GdkFontPrivateFB*) font;
340 mi = T1_GetMetricsInfo(private->t1_font_id, (char *)text, text_length, 0, T1_KERNING);
343 *ascent = ((double)mi.bbox.ury) / 1000.0 * private->size;
345 *descent = ((double)mi.bbox.lly) / -1000.0 * private->size;
347 *width = ((double)mi.width) / 1000.0 * private->size;
349 *lbearing = ((double)mi.bbox.llx) / 1000.0 * private->size;
351 *rbearing = ((double)mi.bbox.urx) / 1000.0 * private->size;
367 gdk_text_extents_wc (GdkFont *font,
368 const GdkWChar *text,
379 realstr = alloca (text_length + 1);
380 for(i = 0; i < text_length; i++)
381 realstr[i] = text[i];
384 return gdk_text_extents (font,