1/* Pango
2 * pangoft2-fontmap.c:
3 *
4 * Copyright (C) 2000 Red Hat Software
5 * Copyright (C) 2000 Tor Lillqvist
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include "config.h"
24
25#include <glib.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <errno.h>
30
31#include <fontconfig/fontconfig.h>
32
33#include "pango-impl-utils.h"
34#include "pangoft2-private.h"
35#include "pangofc-fontmap.h"
36
37typedef struct _PangoFT2Family PangoFT2Family;
38typedef struct _PangoFT2FontMapClass PangoFT2FontMapClass;
39
40/**
41 * PangoFT2FontMap:
42 *
43 * The `PangoFT2FontMap` is the `PangoFontMap` implementation for FreeType fonts.
44 */
45struct _PangoFT2FontMap
46{
47 PangoFcFontMap parent_instance;
48
49 FT_Library library;
50
51 guint serial;
52 double dpi_x;
53 double dpi_y;
54
55 PangoRenderer *renderer;
56};
57
58struct _PangoFT2FontMapClass
59{
60 PangoFcFontMapClass parent_class;
61};
62
63static void pango_ft2_font_map_finalize (GObject *object);
64static PangoFcFont * pango_ft2_font_map_new_font (PangoFcFontMap *fcfontmap,
65 FcPattern *pattern);
66static double pango_ft2_font_map_get_resolution (PangoFcFontMap *fcfontmap,
67 PangoContext *context);
68static guint pango_ft2_font_map_get_serial (PangoFontMap *fontmap);
69static void pango_ft2_font_map_changed (PangoFontMap *fontmap);
70
71static PangoFT2FontMap *pango_ft2_global_fontmap = NULL; /* MT-safe */
72
73G_DEFINE_TYPE (PangoFT2FontMap, pango_ft2_font_map, PANGO_TYPE_FC_FONT_MAP)
74
75static void
76pango_ft2_font_map_class_init (PangoFT2FontMapClass *class)
77{
78 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
79 PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
80 PangoFcFontMapClass *fcfontmap_class = PANGO_FC_FONT_MAP_CLASS (class);
81
82 gobject_class->finalize = pango_ft2_font_map_finalize;
83 fontmap_class->get_serial = pango_ft2_font_map_get_serial;
84 fontmap_class->changed = pango_ft2_font_map_changed;
85 fcfontmap_class->default_substitute = _pango_ft2_font_map_default_substitute;
86 fcfontmap_class->new_font = pango_ft2_font_map_new_font;
87 fcfontmap_class->get_resolution = pango_ft2_font_map_get_resolution;
88}
89
90static void
91pango_ft2_font_map_init (PangoFT2FontMap *fontmap)
92{
93 FT_Error error;
94
95 fontmap->serial = 1;
96 fontmap->library = NULL;
97 fontmap->dpi_x = 72.0;
98 fontmap->dpi_y = 72.0;
99
100 error = FT_Init_FreeType (alibrary: &fontmap->library);
101 if (error != FT_Err_Ok)
102 g_critical ("pango_ft2_font_map_init: Could not initialize freetype");
103}
104
105static void
106pango_ft2_font_map_finalize (GObject *object)
107{
108 PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (object);
109
110 if (ft2fontmap->renderer)
111 g_object_unref (object: ft2fontmap->renderer);
112
113 G_OBJECT_CLASS (pango_ft2_font_map_parent_class)->finalize (object);
114
115 FT_Done_FreeType (library: ft2fontmap->library);
116}
117
118/**
119 * pango_ft2_font_map_new:
120 *
121 * Create a new `PangoFT2FontMap` object.
122 *
123 * A fontmap is used to cache information about available fonts,
124 * and holds certain global parameters such as the resolution and
125 * the default substitute function (see
126 * [method@PangoFT2.FontMap.set_default_substitute]).
127 *
128 * Return value: the newly created fontmap object. Unref
129 * with g_object_unref() when you are finished with it.
130 *
131 * Since: 1.2
132 **/
133PangoFontMap *
134pango_ft2_font_map_new (void)
135{
136 return (PangoFontMap *) g_object_new (PANGO_TYPE_FT2_FONT_MAP, NULL);
137}
138
139static guint
140pango_ft2_font_map_get_serial (PangoFontMap *fontmap)
141{
142 PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
143
144 return ft2fontmap->serial;
145}
146
147static void
148pango_ft2_font_map_changed (PangoFontMap *fontmap)
149{
150 PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
151
152 ft2fontmap->serial++;
153 if (ft2fontmap->serial == 0)
154 ft2fontmap->serial++;
155}
156
157/**
158 * pango_ft2_font_map_set_default_substitute:
159 * @fontmap: a `PangoFT2FontMap`
160 * @func: function to call to to do final config tweaking
161 * on #FcPattern objects.
162 * @data: data to pass to @func
163 * @notify: function to call when @data is no longer used.
164 *
165 * Sets a function that will be called to do final configuration
166 * substitution on a `FcPattern` before it is used to load
167 * the font.
168 *
169 * This function can be used to do things like set
170 * hinting and antialiasing options.
171 *
172 * Deprecated: 1.46: Use [method@PangoFc.FontMap.set_default_substitute]
173 * instead.
174 *
175 * Since: 1.2
176 **/
177void
178pango_ft2_font_map_set_default_substitute (PangoFT2FontMap *fontmap,
179 PangoFT2SubstituteFunc func,
180 gpointer data,
181 GDestroyNotify notify)
182{
183 PangoFcFontMap *fcfontmap = PANGO_FC_FONT_MAP (fontmap);
184 pango_fc_font_map_set_default_substitute(fontmap: fcfontmap, func, data, notify);
185}
186
187/**
188 * pango_ft2_font_map_substitute_changed:
189 * @fontmap: a `PangoFT2FontMap`
190 *
191 * Call this function any time the results of the
192 * default substitution function set with
193 * pango_ft2_font_map_set_default_substitute() change.
194 *
195 * That is, if your substitution function will return different
196 * results for the same input pattern, you must call this function.
197 *
198 * Deprecated: 1.46: Use [method@PangoFc.FontMap.substitute_changed]
199 * instead.
200 *
201 * Since: 1.2
202 **/
203void
204pango_ft2_font_map_substitute_changed (PangoFT2FontMap *fontmap)
205{
206 pango_fc_font_map_substitute_changed(PANGO_FC_FONT_MAP (fontmap));
207}
208
209/**
210 * pango_ft2_font_map_set_resolution:
211 * @fontmap: a `PangoFT2FontMap`
212 * @dpi_x: dots per inch in the X direction
213 * @dpi_y: dots per inch in the Y direction
214 *
215 * Sets the horizontal and vertical resolutions for the fontmap.
216 *
217 * Since: 1.2
218 **/
219void
220pango_ft2_font_map_set_resolution (PangoFT2FontMap *fontmap,
221 double dpi_x,
222 double dpi_y)
223{
224 g_return_if_fail (PANGO_FT2_IS_FONT_MAP (fontmap));
225
226 fontmap->dpi_x = dpi_x;
227 fontmap->dpi_y = dpi_y;
228
229 pango_ft2_font_map_substitute_changed (fontmap);
230}
231
232/**
233 * pango_ft2_font_map_create_context: (skip)
234 * @fontmap: a `PangoFT2FontMap`
235 *
236 * Create a `PangoContext` for the given fontmap.
237 *
238 * Return value: (transfer full): the newly created context; free with
239 * g_object_unref().
240 *
241 * Since: 1.2
242 *
243 * Deprecated: 1.22: Use [method@Pango.FontMap.create_context] instead.
244 **/
245PangoContext *
246pango_ft2_font_map_create_context (PangoFT2FontMap *fontmap)
247{
248 g_return_val_if_fail (PANGO_FT2_IS_FONT_MAP (fontmap), NULL);
249
250 return pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
251}
252
253/**
254 * pango_ft2_get_context: (skip)
255 * @dpi_x: the horizontal DPI of the target device
256 * @dpi_y: the vertical DPI of the target device
257 *
258 * Retrieves a `PangoContext` for the default PangoFT2 fontmap
259 * (see pango_ft2_font_map_for_display()) and sets the resolution
260 * for the default fontmap to @dpi_x by @dpi_y.
261 *
262 * Return value: (transfer full): the new `PangoContext`
263 *
264 * Deprecated: 1.22: Use [method@Pango.FontMap.create_context] instead.
265 **/
266G_GNUC_BEGIN_IGNORE_DEPRECATIONS
267PangoContext *
268pango_ft2_get_context (double dpi_x, double dpi_y)
269{
270 PangoFontMap *fontmap;
271
272 fontmap = pango_ft2_font_map_for_display ();
273 pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (fontmap), dpi_x, dpi_y);
274
275 return pango_font_map_create_context (fontmap);
276}
277G_GNUC_END_IGNORE_DEPRECATIONS
278
279/**
280 * pango_ft2_font_map_for_display: (skip)
281 *
282 * Returns a `PangoFT2FontMap`.
283 *
284 * This font map is cached and should
285 * not be freed. If the font map is no longer needed, it can
286 * be released with pango_ft2_shutdown_display(). Use of the
287 * global PangoFT2 fontmap is deprecated; use pango_ft2_font_map_new()
288 * instead.
289 *
290 * Return value: (transfer none): a `PangoFT2FontMap`.
291 **/
292PangoFontMap *
293pango_ft2_font_map_for_display (void)
294{
295 if (g_once_init_enter (&pango_ft2_global_fontmap))
296 g_once_init_leave (&pango_ft2_global_fontmap, PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ()));
297
298 return PANGO_FONT_MAP (pango_ft2_global_fontmap);
299}
300
301/**
302 * pango_ft2_shutdown_display:
303 *
304 * Free the global fontmap. (See pango_ft2_font_map_for_display())
305 * Use of the global PangoFT2 fontmap is deprecated.
306 **/
307void
308pango_ft2_shutdown_display (void)
309{
310 if (pango_ft2_global_fontmap)
311 {
312 pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (pango_ft2_global_fontmap));
313
314 g_object_unref (object: pango_ft2_global_fontmap);
315
316 pango_ft2_global_fontmap = NULL;
317 }
318}
319
320FT_Library
321_pango_ft2_font_map_get_library (PangoFontMap *fontmap)
322{
323 PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
324
325 return ft2fontmap->library;
326}
327
328
329/**
330 * _pango_ft2_font_map_get_renderer:
331 * @fontmap: a `PangoFT2FontMap`
332 *
333 * Gets the singleton PangoFT2Renderer for this fontmap.
334 *
335 * Return value: the renderer.
336 **/
337PangoRenderer *
338_pango_ft2_font_map_get_renderer (PangoFT2FontMap *ft2fontmap)
339{
340 if (!ft2fontmap->renderer)
341 ft2fontmap->renderer = g_object_new (PANGO_TYPE_FT2_RENDERER, NULL);
342
343 return ft2fontmap->renderer;
344}
345
346void
347_pango_ft2_font_map_default_substitute (PangoFcFontMap *fcfontmap,
348 FcPattern *pattern)
349{
350 PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fcfontmap);
351 FcValue v;
352
353 FcConfigSubstitute (NULL, p: pattern, kind: FcMatchPattern);
354
355 if (fcfontmap->substitute_func)
356 fcfontmap->substitute_func (pattern, fcfontmap->substitute_data);
357
358 if (FcPatternGet (p: pattern, FC_DPI, id: 0, v: &v) == FcResultNoMatch)
359 FcPatternAddDouble (p: pattern, FC_DPI, d: ft2fontmap->dpi_y);
360 FcDefaultSubstitute (pattern);
361}
362
363static double
364pango_ft2_font_map_get_resolution (PangoFcFontMap *fcfontmap,
365 PangoContext *context G_GNUC_UNUSED)
366{
367 return ((PangoFT2FontMap *)fcfontmap)->dpi_y;
368}
369
370static PangoFcFont *
371pango_ft2_font_map_new_font (PangoFcFontMap *fcfontmap,
372 FcPattern *pattern)
373{
374 return (PangoFcFont *)_pango_ft2_font_new (PANGO_FT2_FONT_MAP (fcfontmap), pattern);
375}
376

source code of gtk/subprojects/pango/pango/pangoft2-fontmap.c