ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/pango-font.c
Revision: 1.2
Committed: Wed Dec 26 11:10:53 2007 UTC (16 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_03, rel-2_02, rel-0_9965, rel-0_9964, rel-0_9963, rel-0_9968, rel-2_0, rel-0_9972, rel-0_9973, rel-0_9974, rel-0_9975, rel-0_9976, rel-0_9977, rel-0_9978, rel-0_9971, rel-0_9967, rel-1_21, rel-0_9966
Changes since 1.1: +0 -1 lines
Log Message:
update dejavu fonts

File Contents

# User Rev Content
1 root 1.1 /* Pango
2     * OpenGL Freetype2 handling
3     *
4     * Copyright (C) 1999 Red Hat Software
5     * Copyright (C) 2000 Tor Lillqvist
6     * Copyright (C) 2006 Marc Lehmann <pcg@goof.com>
7     *
8     * This file is free software; you can redistribute it and/or
9     * modify it under the terms of the GNU Library General Public
10     * License as published by the Free Software Foundation; either
11     * version 2 of the License, or (at your option) any later version.
12     *
13     * This file is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16     * Library General Public License for more details.
17     *
18     * You should have received a copy of the GNU Library General Public
19     * License along with this library; if not, write to the
20     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21     * Boston, MA 02111-1307, USA.
22     */
23    
24     #define PANGO_ENABLE_BACKEND
25    
26     #include <string.h>
27     #include <stdlib.h>
28     #include <math.h>
29     #include <glib.h>
30     #include <glib/gprintf.h>
31    
32     #include "pangoopengl.h"
33    
34     #include "pango/pangofc-font.h"
35     #include "pango/pangofc-fontmap.h"
36    
37     #define PANGO_OPENGL_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_OPENGL_FONT, PangoOpenGLFontClass))
38     #define PANGO_OPENGL_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_OPENGL_FONT))
39     #define PANGO_OPENGL_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_OPENGL_FONT, PangoOpenGLFontClass))
40    
41     typedef struct _PangoOpenGLFontClass PangoOpenGLFontClass;
42    
43     struct _PangoOpenGLFontClass
44     {
45     PangoFcFontClass parent_class;
46     };
47    
48     static void pango_opengl_font_finalize (GObject *object);
49    
50     static void pango_opengl_font_get_glyph_extents (PangoFont *font,
51     PangoGlyph glyph,
52     PangoRectangle *ink_rect,
53     PangoRectangle *logical_rect);
54    
55     static FT_Face pango_opengl_font_real_lock_face (PangoFcFont *font);
56     static void pango_opengl_font_real_unlock_face (PangoFcFont *font);
57    
58     PangoOpenGLFont *
59     _pango_opengl_font_new (PangoOpenGLFontMap *fontmap_, FcPattern *pattern)
60     {
61     PangoFontMap *fontmap = PANGO_FONT_MAP (fontmap_);
62     PangoOpenGLFont *font;
63     double d;
64    
65     g_return_val_if_fail (fontmap != NULL, NULL);
66     g_return_val_if_fail (pattern != NULL, NULL);
67    
68     font = (PangoOpenGLFont *)g_object_new (PANGO_TYPE_OPENGL_FONT,
69     "pattern", pattern,
70     NULL);
71    
72     if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &d) == FcResultMatch)
73     font->size = d * PANGO_SCALE;
74    
75     return font;
76     }
77    
78     static void
79     load_fallback_face (PangoOpenGLFont *font, const char *original_file)
80     {
81     PangoFcFont *fcfont = PANGO_FC_FONT (font);
82     FcPattern *sans;
83     FcPattern *matched;
84     FcResult result;
85     FT_Error error;
86     FcChar8 *filename2 = NULL;
87     gchar *name;
88     int id;
89    
90     sans = FcPatternBuild (NULL,
91     FC_FAMILY, FcTypeString, "sans",
92     FC_PIXEL_SIZE, FcTypeDouble, (double)font->size / PANGO_SCALE,
93     NULL);
94    
95     matched = FcFontMatch (NULL, sans, &result);
96    
97     if (FcPatternGetString (matched, FC_FILE, 0, &filename2) != FcResultMatch)
98     goto bail1;
99    
100     if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != FcResultMatch)
101     goto bail1;
102    
103     error = FT_New_Face (_pango_opengl_font_map_get_library (fcfont->fontmap),
104     (char *) filename2, id, &font->face);
105    
106     if (error)
107     {
108     bail1:
109     name = pango_font_description_to_string (fcfont->description);
110     g_warning ("Unable to open font file %s for font %s, exiting\n", filename2, name);
111     exit (1);
112     }
113     else
114     {
115     name = pango_font_description_to_string (fcfont->description);
116     g_warning ("Unable to open font file %s for font %s, falling back to %s\n", original_file, name, filename2);
117     g_free (name);
118     }
119    
120     FcPatternDestroy (sans);
121     FcPatternDestroy (matched);
122     }
123    
124     static void
125     set_transform (PangoOpenGLFont *font)
126     {
127     PangoFcFont *fcfont = (PangoFcFont *)font;
128     FcMatrix *fc_matrix;
129    
130     if (FcPatternGetMatrix (fcfont->font_pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
131     {
132     FT_Matrix ft_matrix;
133    
134     ft_matrix.xx = 0x10000L * fc_matrix->xx;
135     ft_matrix.yy = 0x10000L * fc_matrix->yy;
136     ft_matrix.xy = 0x10000L * fc_matrix->xy;
137     ft_matrix.yx = 0x10000L * fc_matrix->yx;
138    
139     FT_Set_Transform (font->face, &ft_matrix, NULL);
140     }
141     }
142    
143     FT_Face
144     pango_opengl_font_get_face (PangoFont *font)
145     {
146     PangoOpenGLFont *glfont = (PangoOpenGLFont *)font;
147     PangoFcFont *fcfont = (PangoFcFont *)font;
148     FT_Error error;
149     FcPattern *pattern;
150     FcChar8 *filename;
151     FcBool antialias, hinting, autohint;
152     int id;
153    
154     pattern = fcfont->font_pattern;
155    
156     if (!glfont->face)
157     {
158     glfont->load_flags = 0;
159    
160     /* disable antialiasing if requested */
161     if (FcPatternGetBool (pattern, FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
162     antialias = FcTrue;
163    
164     glfont->load_flags |= FT_LOAD_NO_BITMAP;
165    
166     /* disable hinting if requested */
167     if (FcPatternGetBool (pattern, FC_HINTING, 0, &hinting) != FcResultMatch)
168     hinting = FcTrue;
169    
170     if (!hinting)
171     glfont->load_flags |= FT_LOAD_NO_HINTING;
172    
173     /* force autohinting if requested */
174     if (FcPatternGetBool (pattern, FC_AUTOHINT, 0, &autohint) != FcResultMatch)
175     autohint = FcFalse;
176    
177     if (autohint)
178     glfont->load_flags |= FT_LOAD_FORCE_AUTOHINT;
179    
180     if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch)
181     goto bail0;
182    
183     if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
184     goto bail0;
185    
186     error = FT_New_Face (_pango_opengl_font_map_get_library (fcfont->fontmap),
187     (char *)filename, id, &glfont->face);
188    
189     if (error != FT_Err_Ok)
190     {
191     bail0:
192     load_fallback_face (glfont, (char *)filename);
193     }
194    
195     g_assert (glfont->face);
196    
197     set_transform (glfont);
198    
199     error = FT_Set_Char_Size (glfont->face,
200     PANGO_PIXELS_26_6 (glfont->size),
201     PANGO_PIXELS_26_6 (glfont->size),
202     0, 0);
203     if (error)
204     g_warning ("Error in FT_Set_Char_Size: %d", error);
205     }
206    
207     return glfont->face;
208     }
209    
210     G_DEFINE_TYPE (PangoOpenGLFont, pango_opengl_font, PANGO_TYPE_FC_FONT)
211    
212     static void
213     pango_opengl_font_init (PangoOpenGLFont *font)
214     {
215     font->face = NULL;
216     font->size = 0;
217     font->glyph_info = g_hash_table_new (NULL, NULL);
218     }
219    
220     static void
221     pango_opengl_font_class_init (PangoOpenGLFontClass *class)
222     {
223     GObjectClass *object_class = G_OBJECT_CLASS (class);
224     PangoFontClass *font_class = PANGO_FONT_CLASS (class);
225     PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class);
226    
227     object_class->finalize = pango_opengl_font_finalize;
228    
229     font_class->get_glyph_extents = pango_opengl_font_get_glyph_extents;
230    
231     fc_font_class->lock_face = pango_opengl_font_real_lock_face;
232     fc_font_class->unlock_face = pango_opengl_font_real_unlock_face;
233     }
234    
235     static PangoOpenGLGlyphInfo *
236     pango_opengl_font_get_glyph_info (PangoFont *font_, PangoGlyph glyph, gboolean create)
237     {
238     PangoOpenGLFont *font = (PangoOpenGLFont *)font_;
239     PangoFcFont *fcfont = (PangoFcFont *)font;
240     PangoOpenGLGlyphInfo *info;
241    
242     info = g_hash_table_lookup (font->glyph_info, GUINT_TO_POINTER (glyph));
243    
244     if ((info == NULL) && create)
245     {
246     info = g_slice_new0 (PangoOpenGLGlyphInfo);
247    
248     pango_fc_font_get_raw_extents (fcfont, font->load_flags,
249     glyph,
250     &info->ink_rect,
251     &info->logical_rect);
252    
253     g_hash_table_insert (font->glyph_info, GUINT_TO_POINTER(glyph), info);
254     }
255    
256     return info;
257     }
258    
259     PangoGlyph
260     pango_opengl_get_unknown_glyph (PangoFont *font)
261     {
262     FT_Face face = pango_opengl_font_get_face (font);
263    
264     if (face && FT_IS_SFNT (face))
265     /* TrueType fonts have an 'unknown glyph' box on glyph index 0 */
266     return 0;
267     else
268     return PANGO_GLYPH_EMPTY;
269     }
270    
271     static void
272     pango_opengl_font_get_glyph_extents (PangoFont *font,
273     PangoGlyph glyph,
274     PangoRectangle *ink_rect,
275     PangoRectangle *logical_rect)
276     {
277     PangoOpenGLGlyphInfo *info;
278    
279     if (glyph == PANGO_GLYPH_EMPTY)
280     {
281     if (ink_rect)
282     ink_rect->x = ink_rect->y = ink_rect->height = ink_rect->width = 0;
283     if (logical_rect)
284     logical_rect->x = logical_rect->y = logical_rect->height = logical_rect->width = 0;
285     return;
286     }
287    
288     if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)
289     {
290     glyph = pango_opengl_get_unknown_glyph (font);
291     if (glyph == PANGO_GLYPH_EMPTY)
292     {
293     /* No unknown glyph found for the font, draw a box */
294     PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL);
295    
296     if (metrics)
297     {
298     if (ink_rect)
299     {
300     ink_rect->x = PANGO_SCALE;
301     ink_rect->width = metrics->approximate_char_width - 2 * PANGO_SCALE;
302     ink_rect->y = - (metrics->ascent - PANGO_SCALE);
303     ink_rect->height = metrics->ascent + metrics->descent - 2 * PANGO_SCALE;
304     }
305     if (logical_rect)
306     {
307     logical_rect->x = 0;
308     logical_rect->width = metrics->approximate_char_width;
309     logical_rect->y = -metrics->ascent;
310     logical_rect->height = metrics->ascent + metrics->descent;
311     }
312    
313     pango_font_metrics_unref (metrics);
314     }
315     else
316     {
317     if (ink_rect)
318     ink_rect->x = ink_rect->y = ink_rect->height = ink_rect->width = 0;
319     if (logical_rect)
320     logical_rect->x = logical_rect->y = logical_rect->height = logical_rect->width = 0;
321     }
322    
323     return;
324     }
325     }
326    
327     info = pango_opengl_font_get_glyph_info (font, glyph, TRUE);
328    
329     if (ink_rect)
330     *ink_rect = info->ink_rect;
331     if (logical_rect)
332     *logical_rect = info->logical_rect;
333     }
334    
335     int
336     pango_opengl_font_get_kerning (PangoFont *font,
337     PangoGlyph left,
338     PangoGlyph right)
339     {
340     PangoFcFont *fc_font = PANGO_FC_FONT (font);
341    
342     FT_Face face;
343     FT_Error error;
344     FT_Vector kerning;
345    
346     face = pango_fc_font_lock_face (fc_font);
347     if (!face)
348     return 0;
349    
350     if (!FT_HAS_KERNING (face))
351     {
352     pango_fc_font_unlock_face (fc_font);
353     return 0;
354     }
355    
356     error = FT_Get_Kerning (face, left, right, ft_kerning_default, &kerning);
357     if (error != FT_Err_Ok)
358     {
359     pango_fc_font_unlock_face (fc_font);
360     return 0;
361     }
362    
363     pango_fc_font_unlock_face (fc_font);
364     return PANGO_UNITS_26_6 (kerning.x);
365     }
366    
367     static FT_Face
368     pango_opengl_font_real_lock_face (PangoFcFont *font)
369     {
370     return pango_opengl_font_get_face ((PangoFont *)font);
371     }
372    
373     static void
374     pango_opengl_font_real_unlock_face (PangoFcFont *font)
375     {
376     }
377    
378     static gboolean
379     pango_opengl_free_glyph_info_callback (gpointer key, gpointer value, gpointer data)
380     {
381     PangoOpenGLFont *font = PANGO_OPENGL_FONT (data);
382     PangoOpenGLGlyphInfo *info = value;
383    
384     if (font->glyph_cache_destroy && info->cached_glyph)
385     (*font->glyph_cache_destroy) (info->cached_glyph);
386    
387     g_slice_free (PangoOpenGLGlyphInfo, info);
388     return TRUE;
389     }
390    
391     static void
392     pango_opengl_font_finalize (GObject *object)
393     {
394     PangoOpenGLFont *font = (PangoOpenGLFont *)object;
395    
396     if (font->face)
397     {
398     FT_Done_Face (font->face);
399     font->face = NULL;
400     }
401    
402     g_hash_table_foreach_remove (font->glyph_info, pango_opengl_free_glyph_info_callback, object);
403     g_hash_table_destroy (font->glyph_info);
404    
405     G_OBJECT_CLASS (pango_opengl_font_parent_class)->finalize (object);
406     }
407    
408     PangoCoverage *
409     pango_opengl_font_get_coverage (PangoFont *font, PangoLanguage *language)
410     {
411     return pango_font_get_coverage (font, language);
412     }
413    
414     void *
415     _pango_opengl_font_get_cache_glyph_data (PangoFont *font, int glyph_index)
416     {
417     PangoOpenGLGlyphInfo *info = pango_opengl_font_get_glyph_info (font, glyph_index, FALSE);
418    
419     return info ? info->cached_glyph : 0;
420     }
421    
422     void
423     _pango_opengl_font_set_cache_glyph_data (PangoFont *font, int glyph_index, void *cached_glyph)
424     {
425     PangoOpenGLGlyphInfo *info = pango_opengl_font_get_glyph_info (font, glyph_index, TRUE);
426     info->cached_glyph = cached_glyph;
427     }
428    
429     void
430     _pango_opengl_font_set_glyph_cache_destroy (PangoFont *font, GDestroyNotify destroy_notify)
431     {
432     PANGO_OPENGL_FONT (font)->glyph_cache_destroy = destroy_notify;
433     }