]> Pileus Git - ~andy/gtk/blob - gdk/linux-fb/gdkfont-fb.c
Do implicit button grabs, even if the window doesn't want the event.
[~andy/gtk] / gdk / linux-fb / gdkfont-fb.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 #include <math.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "gdkfont.h"
31 #include "gdkprivate-fb.h"
32 #include "gdkpango.h"
33
34 #include <pango/pango.h>
35
36 #include <freetype/freetype.h>
37 #if !defined(FREETYPE_MAJOR) || FREETYPE_MAJOR != 2
38 #error "We need Freetype 2.0 (beta?)"
39 #endif
40
41 GdkFont*
42 gdk_font_from_description (PangoFontDescription *font_desc)
43 {
44   GdkFont *font;
45   GdkFontPrivateFB *private;
46
47   g_return_val_if_fail (font_desc, NULL);
48
49   private = g_new0 (GdkFontPrivateFB, 1);
50   font = (GdkFont *)private;
51   private->base.ref_count = 1;
52
53   return font;
54 }
55
56 /* ********************* */
57 #if 0
58 static GHashTable *font_name_hash = NULL;
59 static GHashTable *fontset_name_hash = NULL;
60
61 static void
62 gdk_font_hash_insert (GdkFontType type, GdkFont *font, const gchar *font_name)
63 {
64   GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
65   GHashTable **hashp = (type == GDK_FONT_FONT) ?
66     &font_name_hash : &fontset_name_hash;
67
68   if (!*hashp)
69     *hashp = g_hash_table_new (g_str_hash, g_str_equal);
70
71   private->names = g_slist_prepend (private->names, g_strdup (font_name));
72   g_hash_table_insert (*hashp, private->names->data, font);
73 }
74
75 static void
76 gdk_font_hash_remove (GdkFontType type, GdkFont *font)
77 {
78   GdkFontPrivateFB *private = (GdkFontPrivateFB *)font;
79   GSList *tmp_list;
80   GHashTable *hash = (type == GDK_FONT_FONT) ?
81     font_name_hash : fontset_name_hash;
82
83   tmp_list = private->names;
84   while (tmp_list)
85     {
86       g_hash_table_remove (hash, tmp_list->data);
87       g_free (tmp_list->data);
88       
89       tmp_list = tmp_list->next;
90     }
91
92   g_slist_free (private->names);
93   private->names = NULL;
94 }
95
96 static GdkFont *
97 gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
98 {
99   GdkFont *result;
100   GHashTable *hash = (type == GDK_FONT_FONT) ?
101     font_name_hash : fontset_name_hash;
102
103   if (!hash)
104     return NULL;
105   else
106     {
107       result = g_hash_table_lookup (hash, font_name);
108       if (result)
109         gdk_font_ref (result);
110       
111       return result;
112     }
113 }
114
115 GdkFont*
116 gdk_font_load (const gchar *font_name)
117 {
118   GdkFont *font;
119   GdkFontPrivateFB *private;
120
121   g_return_val_if_fail (font_name != NULL, NULL);
122
123   font = gdk_font_hash_lookup (GDK_FONT_FONTSET, font_name);
124   if (font)
125     return font;
126
127   {
128     char **pieces;
129     BBox bb;
130     
131     private = g_new0 (GdkFontPrivateFB, 1);
132     private->base.ref_count = 1;
133     private->names = NULL;
134
135     pieces = g_strsplit(font_name, "-", 2);
136     if(pieces[1])
137       {
138         private->size = atof(pieces[1]);
139         private->t1_font_id = T1_AddFont(pieces[0]);
140       }
141     else
142       private->t1_font_id = T1_AddFont((char *)font_name);
143     g_strfreev(pieces);
144
145     T1_LoadFont(private->t1_font_id);
146     CreateNewFontSize(private->t1_font_id, private->size, FALSE);
147
148     font = (GdkFont*) private;
149     font->type = GDK_FONT_FONTSET;
150
151     bb = T1_GetFontBBox(private->t1_font_id);
152
153     font->ascent = ((double)bb.ury) / 1000.0 * private->size;
154     font->descent = ((double)bb.lly) / -1000.0 * private->size;
155   }
156
157   gdk_font_hash_insert (GDK_FONT_FONTSET, font, font_name);
158
159   return font;
160 }
161
162 GdkFont*
163 gdk_fontset_load (const gchar *fontset_name)
164 {
165   return gdk_font_load(fontset_name);
166 }
167 #endif
168
169 GdkFont *
170 gdk_font_load (const gchar *font_name)
171 {
172   return NULL;
173 }
174
175 void
176 _gdk_font_destroy (GdkFont *font)
177 {
178 #if 0
179   gdk_font_hash_remove (font->type, font);
180 #endif
181       
182   switch (font->type)
183     {
184     case GDK_FONT_FONT:
185       break;
186     case GDK_FONT_FONTSET:
187       break;
188     default:
189       g_error ("unknown font type.");
190       break;
191     }
192   g_free (font);
193 }
194
195 gint
196 _gdk_font_strlen (GdkFont     *font,
197                   const gchar *str)
198 {
199   GdkFontPrivateFB *font_private;
200   gint length = 0;
201
202   g_return_val_if_fail (font != NULL, -1);
203   g_return_val_if_fail (str != NULL, -1);
204
205   font_private = (GdkFontPrivateFB*) font;
206
207   if (font->type == GDK_FONT_FONT)
208     {
209       guint16 *string_2b = (guint16 *)str;
210             
211       while (*(string_2b++))
212         length++;
213     }
214   else if (font->type == GDK_FONT_FONTSET)
215     {
216       length = strlen (str);
217     }
218   else
219     g_error("undefined font type\n");
220
221   return length;
222 }
223
224 gint
225 gdk_font_id (const GdkFont *font)
226 {
227   const GdkFontPrivateFB *font_private;
228
229   g_return_val_if_fail (font != NULL, 0);
230
231   font_private = (const GdkFontPrivateFB*) font;
232
233   if (font->type == GDK_FONT_FONT)
234     {
235       return -1;
236     }
237   else
238     {
239       return 0;
240     }
241 }
242
243 gint
244 gdk_font_equal (const GdkFont *fonta,
245                 const GdkFont *fontb)
246 {
247   const GdkFontPrivateFB *privatea;
248   const GdkFontPrivateFB *privateb;
249
250   g_return_val_if_fail (fonta != NULL, FALSE);
251   g_return_val_if_fail (fontb != NULL, FALSE);
252
253   privatea = (const GdkFontPrivateFB*) fonta;
254   privateb = (const GdkFontPrivateFB*) fontb;
255
256   if(fonta == fontb)
257     return TRUE;
258 #if 0
259   if(privatea->t1_font_id == privateb->t1_font_id
260      && privatea->size == privateb->size)
261     return TRUE;
262 #endif
263
264   return FALSE;
265 }
266
267 gint
268 gdk_text_width (GdkFont      *font,
269                 const gchar  *text,
270                 gint          text_length)
271 {
272 #if 0
273   GdkFontPrivateFB *private;
274   gint width;
275   double n;
276
277   g_return_val_if_fail (font != NULL, -1);
278   g_return_val_if_fail (text != NULL, -1);
279
280   private = (GdkFontPrivateFB*) font;
281
282   switch (font->type)
283     {
284     case GDK_FONT_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);
288       width = ceil(n);
289       break;
290     default:
291       width = 0;
292       break;
293     }
294
295   return width;
296 #else
297   return 0;
298 #endif
299 }
300
301 gint
302 gdk_text_width_wc (GdkFont        *font,
303                    const GdkWChar *text,
304                    gint            text_length)
305 {
306 #if 0
307   char *realstr;
308   int i;
309
310   realstr = alloca(text_length + 1);
311   for(i = 0; i < text_length; i++)
312     realstr[i] = text[i];
313   realstr[i] = '\0';
314
315   return gdk_text_width(font, realstr, text_length);
316 #else
317   return 0;
318 #endif
319 }
320
321 void
322 gdk_text_extents (GdkFont     *font,
323                   const gchar *text,
324                   gint         text_length,
325                   gint        *lbearing,
326                   gint        *rbearing,
327                   gint        *width,
328                   gint        *ascent,
329                   gint        *descent)
330 {
331 #if 0
332   GdkFontPrivateFB *private;
333   METRICSINFO mi;
334
335   g_return_if_fail (font != NULL);
336   g_return_if_fail (text != NULL);
337
338   private = (GdkFontPrivateFB*) font;
339
340   mi = T1_GetMetricsInfo(private->t1_font_id, (char *)text, text_length, 0, T1_KERNING);
341
342   if(ascent)
343     *ascent = ((double)mi.bbox.ury) / 1000.0 * private->size;
344   if(descent)
345     *descent = ((double)mi.bbox.lly) / -1000.0 * private->size;
346   if(width)
347     *width = ((double)mi.width) / 1000.0 * private->size;
348   if(lbearing)
349     *lbearing = ((double)mi.bbox.llx) / 1000.0 * private->size;
350   if(rbearing)
351     *rbearing = ((double)mi.bbox.urx) / 1000.0 * private->size;
352 #else
353   if(ascent)
354     *ascent = 0;
355   if(descent)
356     *descent = 0;
357   if(width)
358     *width = 0;
359   if(lbearing)
360     *lbearing = 0;
361   if(rbearing)
362     *rbearing = 0;
363 #endif
364 }
365
366 void
367 gdk_text_extents_wc (GdkFont        *font,
368                      const GdkWChar *text,
369                      gint            text_length,
370                      gint           *lbearing,
371                      gint           *rbearing,
372                      gint           *width,
373                      gint           *ascent,
374                      gint           *descent)
375 {
376   char *realstr;
377   int i;
378
379   realstr = alloca (text_length + 1);
380   for(i = 0; i < text_length; i++)
381     realstr[i] = text[i];
382   realstr[i] = '\0';
383
384   return gdk_text_extents (font,
385                            realstr,
386                            text_length,
387                            lbearing,
388                            rbearing,
389                            width,
390                            ascent,
391                            descent);
392 }