1/* Pango
2 * pango-fontset.c:
3 *
4 * Copyright (C) 2001 Red Hat Software
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include "config.h"
23
24/*
25 * PangoFontset
26 */
27
28#include "pango-types.h"
29#include "pango-font-private.h"
30#include "pango-fontset.h"
31#include "pango-impl-utils.h"
32
33static PangoFontMetrics *pango_fontset_real_get_metrics (PangoFontset *fontset);
34
35
36G_DEFINE_ABSTRACT_TYPE (PangoFontset, pango_fontset, G_TYPE_OBJECT);
37
38static void
39pango_fontset_init (PangoFontset *self)
40{
41}
42
43static void
44pango_fontset_class_init (PangoFontsetClass *class)
45{
46 class->get_metrics = pango_fontset_real_get_metrics;
47}
48
49
50/**
51 * pango_fontset_get_font:
52 * @fontset: a `PangoFontset`
53 * @wc: a Unicode character
54 *
55 * Returns the font in the fontset that contains the best
56 * glyph for a Unicode character.
57 *
58 * Return value: (transfer full): a `PangoFont`
59 */
60PangoFont *
61pango_fontset_get_font (PangoFontset *fontset,
62 guint wc)
63{
64
65 g_return_val_if_fail (PANGO_IS_FONTSET (fontset), NULL);
66
67 return PANGO_FONTSET_GET_CLASS (fontset)->get_font (fontset, wc);
68}
69
70/**
71 * pango_fontset_get_metrics:
72 * @fontset: a `PangoFontset`
73 *
74 * Get overall metric information for the fonts in the fontset.
75 *
76 * Return value: a `PangoFontMetrics` object
77 */
78PangoFontMetrics *
79pango_fontset_get_metrics (PangoFontset *fontset)
80{
81 g_return_val_if_fail (PANGO_IS_FONTSET (fontset), NULL);
82
83 return PANGO_FONTSET_GET_CLASS (fontset)->get_metrics (fontset);
84}
85
86/**
87 * pango_fontset_foreach:
88 * @fontset: a `PangoFontset`
89 * @func: (closure data) (scope call): Callback function
90 * @data: (closure): data to pass to the callback function
91 *
92 * Iterates through all the fonts in a fontset, calling @func for
93 * each one.
94 *
95 * If @func returns %TRUE, that stops the iteration.
96 *
97 * Since: 1.4
98 */
99void
100pango_fontset_foreach (PangoFontset *fontset,
101 PangoFontsetForeachFunc func,
102 gpointer data)
103{
104 g_return_if_fail (PANGO_IS_FONTSET (fontset));
105 g_return_if_fail (func != NULL);
106
107 PANGO_FONTSET_GET_CLASS (fontset)->foreach (fontset, func, data);
108}
109
110static gboolean
111get_first_metrics_foreach (PangoFontset *fontset,
112 PangoFont *font,
113 gpointer data)
114{
115 PangoFontMetrics *fontset_metrics = data;
116 PangoLanguage *language = PANGO_FONTSET_GET_CLASS (fontset)->get_language (fontset);
117 PangoFontMetrics *font_metrics = pango_font_get_metrics (font, language);
118 guint save_ref_count;
119
120 /* Initialize the fontset metrics to metrics of the first font in the
121 * fontset; saving the refcount and restoring it is a bit of hack but avoids
122 * having to update this code for each metrics addition.
123 */
124 save_ref_count = fontset_metrics->ref_count;
125 *fontset_metrics = *font_metrics;
126 fontset_metrics->ref_count = save_ref_count;
127
128 pango_font_metrics_unref (metrics: font_metrics);
129
130 return TRUE; /* Stops iteration */
131}
132
133static PangoFontMetrics *
134pango_fontset_real_get_metrics (PangoFontset *fontset)
135{
136 PangoFontMetrics *metrics, *raw_metrics;
137 const char *sample_str;
138 const char *p;
139 int count;
140 GHashTable *fonts_seen;
141 PangoFont *font;
142 PangoLanguage *language;
143
144 language = PANGO_FONTSET_GET_CLASS (fontset)->get_language (fontset);
145 sample_str = pango_language_get_sample_string (language);
146
147 count = 0;
148 metrics = pango_font_metrics_new ();
149 fonts_seen = g_hash_table_new_full (NULL, NULL, key_destroy_func: g_object_unref, NULL);
150
151 /* Initialize the metrics from the first font in the fontset */
152 pango_fontset_foreach (fontset, func: get_first_metrics_foreach, data: metrics);
153
154 p = sample_str;
155 while (*p)
156 {
157 gunichar wc = g_utf8_get_char (p);
158 font = pango_fontset_get_font (fontset, wc);
159 if (font)
160 {
161 if (g_hash_table_lookup (hash_table: fonts_seen, key: font) == NULL)
162 {
163 raw_metrics = pango_font_get_metrics (font, language);
164 g_hash_table_insert (hash_table: fonts_seen, key: font, value: font);
165
166 if (count == 0)
167 {
168 metrics->ascent = raw_metrics->ascent;
169 metrics->descent = raw_metrics->descent;
170 metrics->approximate_char_width = raw_metrics->approximate_char_width;
171 metrics->approximate_digit_width = raw_metrics->approximate_digit_width;
172 }
173 else
174 {
175 metrics->ascent = MAX (metrics->ascent, raw_metrics->ascent);
176 metrics->descent = MAX (metrics->descent, raw_metrics->descent);
177 metrics->approximate_char_width += raw_metrics->approximate_char_width;
178 metrics->approximate_digit_width += raw_metrics->approximate_digit_width;
179 }
180 count++;
181 pango_font_metrics_unref (metrics: raw_metrics);
182 }
183 else
184 g_object_unref (object: font);
185 }
186
187 p = g_utf8_next_char (p);
188 }
189
190 g_hash_table_destroy (hash_table: fonts_seen);
191
192 if (count)
193 {
194 metrics->approximate_char_width /= count;
195 metrics->approximate_digit_width /= count;
196 }
197
198 return metrics;
199}
200

source code of gtk/subprojects/pango/pango/pango-fontset.c