1 /* GTK - The GIMP Toolkit
2  * gtkfontchooser.c - Abstract interface for font file selectors GUIs
3  *
4  * Copyright (C) 2006, Emmanuele Bassi
5  * Copyright (C) 2011 Alberto Ruiz <aruiz@gnome.org>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser 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  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include "gtkfontchooser.h"
24 #include "gtkfontchooserprivate.h"
25 #include "gtkintl.h"
26 #include "gtktypebuiltins.h"
27 #include "gtkprivate.h"
28 
29 /**
30  * SECTION:gtkfontchooser
31  * @Short_description: Interface implemented by widgets displaying fonts
32  * @Title: GtkFontChooser
33  * @See_also: #GtkFontChooserDialog, #GtkFontChooserWidget, #GtkFontButton
34  *
35  * #GtkFontChooser is an interface that can be implemented by widgets
36  * displaying the list of fonts. In GTK+, the main objects
37  * that implement this interface are #GtkFontChooserWidget,
38  * #GtkFontChooserDialog and #GtkFontButton. The GtkFontChooser interface
39  * has been introducted in GTK+ 3.2.
40  */
41 
42 enum
43 {
44   SIGNAL_FONT_ACTIVATED,
45   LAST_SIGNAL
46 };
47 
48 static guint chooser_signals[LAST_SIGNAL];
49 
50 typedef GtkFontChooserIface GtkFontChooserInterface;
51 G_DEFINE_INTERFACE (GtkFontChooser, gtk_font_chooser, G_TYPE_OBJECT);
52 
53 static void
gtk_font_chooser_default_init(GtkFontChooserInterface * iface)54 gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
55 {
56   /**
57    * GtkFontChooser:font:
58    *
59    * The font description as a string, e.g. "Sans Italic 12".
60    */
61   g_object_interface_install_property
62      (iface,
63       g_param_spec_string ("font",
64                           P_("Font"),
65                            P_("Font description as a string, e.g. \"Sans Italic 12\""),
66                            GTK_FONT_CHOOSER_DEFAULT_FONT_NAME,
67                            GTK_PARAM_READWRITE));
68 
69   /**
70    * GtkFontChooser:font-desc:
71    *
72    * The font description as a #PangoFontDescription.
73    */
74   g_object_interface_install_property
75      (iface,
76       g_param_spec_boxed ("font-desc",
77                           P_("Font description"),
78                           P_("Font description as a PangoFontDescription struct"),
79                           PANGO_TYPE_FONT_DESCRIPTION,
80                           GTK_PARAM_READWRITE));
81 
82   /**
83    * GtkFontChooser:preview-text:
84    *
85    * The string with which to preview the font.
86    */
87   g_object_interface_install_property
88      (iface,
89       g_param_spec_string ("preview-text",
90                           P_("Preview text"),
91                           P_("The text to display in order to demonstrate the selected font"),
92                           pango_language_get_sample_string (NULL),
93                           GTK_PARAM_READWRITE));
94 
95   /**
96    * GtkFontChooser:show-preview-entry:
97    *
98    * Whether to show an entry to change the preview text.
99    */
100   g_object_interface_install_property
101      (iface,
102       g_param_spec_boolean ("show-preview-entry",
103                           P_("Show preview text entry"),
104                           P_("Whether the preview text entry is shown or not"),
105                           TRUE,
106                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
107 
108   /**
109    * GtkFontChooser:level:
110    *
111    * The level of granularity to offer for selecting fonts.
112    *
113    * Since: 3.24.1
114    */
115   g_object_interface_install_property
116      (iface,
117       g_param_spec_flags ("level",
118                           P_("Selection level"),
119                           P_("Whether to select family, face or font"),
120                           GTK_TYPE_FONT_CHOOSER_LEVEL,
121                           GTK_FONT_CHOOSER_LEVEL_FAMILY |
122                           GTK_FONT_CHOOSER_LEVEL_STYLE |
123                           GTK_FONT_CHOOSER_LEVEL_SIZE,
124                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
125 
126   /**
127    * GtkFontChooser:font-features:
128    *
129    * The selected font features, in a format that is compatible with
130    * CSS and with Pango attributes.
131    *
132    * Since: 3.24.1
133    */
134   g_object_interface_install_property
135      (iface,
136       g_param_spec_string ("font-features",
137                           P_("Font features"),
138                           P_("Font features as a string"),
139                           "",
140                           GTK_PARAM_READABLE));
141 
142   /**
143    * GtkFontChooser:language:
144    *
145    * The language for which the #GtkFontChooser:font-features were
146    * selected, in a format that is compatible with CSS and with Pango
147    * attributes.
148    *
149    * Since: 3.24.1
150    */
151   g_object_interface_install_property
152      (iface,
153       g_param_spec_string ("language",
154                           P_("Language"),
155                           P_("Language for which features have been selected"),
156                           "",
157                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
158 
159   /**
160    * GtkFontChooser::font-activated:
161    * @self: the object which received the signal
162    * @fontname: the font name
163    *
164    * Emitted when a font is activated.
165    * This usually happens when the user double clicks an item,
166    * or an item is selected and the user presses one of the keys
167    * Space, Shift+Space, Return or Enter.
168     */
169   chooser_signals[SIGNAL_FONT_ACTIVATED] =
170     g_signal_new (I_("font-activated"),
171                   GTK_TYPE_FONT_CHOOSER,
172                   G_SIGNAL_RUN_FIRST,
173                   G_STRUCT_OFFSET (GtkFontChooserIface, font_activated),
174                   NULL, NULL,
175                   NULL,
176                   G_TYPE_NONE,
177                   1, G_TYPE_STRING);
178 }
179 
180 /**
181  * gtk_font_chooser_get_font_family:
182  * @fontchooser: a #GtkFontChooser
183  *
184  * Gets the #PangoFontFamily representing the selected font family.
185  * Font families are a collection of font faces.
186  *
187  * If the selected font is not installed, returns %NULL.
188  *
189  * Returns: (nullable) (transfer none): A #PangoFontFamily representing the
190  *     selected font family, or %NULL. The returned object is owned by @fontchooser
191  *     and must not be modified or freed.
192  *
193  * Since: 3.2
194  */
195 PangoFontFamily *
gtk_font_chooser_get_font_family(GtkFontChooser * fontchooser)196 gtk_font_chooser_get_font_family (GtkFontChooser *fontchooser)
197 {
198   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
199 
200   return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_family (fontchooser);
201 }
202 
203 /**
204  * gtk_font_chooser_get_font_face:
205  * @fontchooser: a #GtkFontChooser
206  *
207  * Gets the #PangoFontFace representing the selected font group
208  * details (i.e. family, slant, weight, width, etc).
209  *
210  * If the selected font is not installed, returns %NULL.
211  *
212  * Returns: (nullable) (transfer none): A #PangoFontFace representing the
213  *     selected font group details, or %NULL. The returned object is owned by
214  *     @fontchooser and must not be modified or freed.
215  *
216  * Since: 3.2
217  */
218 PangoFontFace *
gtk_font_chooser_get_font_face(GtkFontChooser * fontchooser)219 gtk_font_chooser_get_font_face (GtkFontChooser *fontchooser)
220 {
221   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
222 
223   return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_face (fontchooser);
224 }
225 
226 /**
227  * gtk_font_chooser_get_font_size:
228  * @fontchooser: a #GtkFontChooser
229  *
230  * The selected font size.
231  *
232  * Returns: A n integer representing the selected font size,
233  *     or -1 if no font size is selected.
234  *
235  * Since: 3.2
236  */
237 gint
gtk_font_chooser_get_font_size(GtkFontChooser * fontchooser)238 gtk_font_chooser_get_font_size (GtkFontChooser *fontchooser)
239 {
240   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), -1);
241 
242   return GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_size (fontchooser);
243 }
244 
245 /**
246  * gtk_font_chooser_get_font:
247  * @fontchooser: a #GtkFontChooser
248  *
249  * Gets the currently-selected font name.
250  *
251  * Note that this can be a different string than what you set with
252  * gtk_font_chooser_set_font(), as the font chooser widget may
253  * normalize font names and thus return a string with a different
254  * structure. For example, “Helvetica Italic Bold 12” could be
255  * normalized to “Helvetica Bold Italic 12”.
256  *
257  * Use pango_font_description_equal() if you want to compare two
258  * font descriptions.
259  *
260  * Returns: (nullable) (transfer full): A string with the name
261  *     of the current font, or %NULL if  no font is selected. You must
262  *     free this string with g_free().
263  *
264  * Since: 3.2
265  */
266 gchar *
gtk_font_chooser_get_font(GtkFontChooser * fontchooser)267 gtk_font_chooser_get_font (GtkFontChooser *fontchooser)
268 {
269   gchar *fontname;
270 
271   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
272 
273   g_object_get (fontchooser, "font", &fontname, NULL);
274 
275 
276   return fontname;
277 }
278 
279 /**
280  * gtk_font_chooser_set_font:
281  * @fontchooser: a #GtkFontChooser
282  * @fontname: a font name like “Helvetica 12” or “Times Bold 18”
283  *
284  * Sets the currently-selected font.
285  *
286  * Since: 3.2
287  */
288 void
gtk_font_chooser_set_font(GtkFontChooser * fontchooser,const gchar * fontname)289 gtk_font_chooser_set_font (GtkFontChooser *fontchooser,
290                            const gchar    *fontname)
291 {
292   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
293   g_return_if_fail (fontname != NULL);
294 
295   g_object_set (fontchooser, "font", fontname, NULL);
296 }
297 
298 /**
299  * gtk_font_chooser_get_font_desc:
300  * @fontchooser: a #GtkFontChooser
301  *
302  * Gets the currently-selected font.
303  *
304  * Note that this can be a different string than what you set with
305  * gtk_font_chooser_set_font(), as the font chooser widget may
306  * normalize font names and thus return a string with a different
307  * structure. For example, “Helvetica Italic Bold 12” could be
308  * normalized to “Helvetica Bold Italic 12”.
309  *
310  * Use pango_font_description_equal() if you want to compare two
311  * font descriptions.
312  *
313  * Returns: (nullable) (transfer full): A #PangoFontDescription for the
314  *     current font, or %NULL if  no font is selected.
315  *
316  * Since: 3.2
317  */
318 PangoFontDescription *
gtk_font_chooser_get_font_desc(GtkFontChooser * fontchooser)319 gtk_font_chooser_get_font_desc (GtkFontChooser *fontchooser)
320 {
321   PangoFontDescription *font_desc;
322 
323   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
324 
325   g_object_get (fontchooser, "font-desc", &font_desc, NULL);
326 
327   return font_desc;
328 }
329 
330 /**
331  * gtk_font_chooser_set_font_desc:
332  * @fontchooser: a #GtkFontChooser
333  * @font_desc: a #PangoFontDescription
334  *
335  * Sets the currently-selected font from @font_desc.
336  *
337  * Since: 3.2
338  */
339 void
gtk_font_chooser_set_font_desc(GtkFontChooser * fontchooser,const PangoFontDescription * font_desc)340 gtk_font_chooser_set_font_desc (GtkFontChooser             *fontchooser,
341                                 const PangoFontDescription *font_desc)
342 {
343   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
344   g_return_if_fail (font_desc != NULL);
345 
346   g_object_set (fontchooser, "font-desc", font_desc, NULL);
347 }
348 
349 /**
350  * gtk_font_chooser_get_preview_text:
351  * @fontchooser: a #GtkFontChooser
352  *
353  * Gets the text displayed in the preview area.
354  *
355  * Returns: (transfer full): the text displayed in the
356  *     preview area
357  *
358  * Since: 3.2
359  */
360 gchar *
gtk_font_chooser_get_preview_text(GtkFontChooser * fontchooser)361 gtk_font_chooser_get_preview_text (GtkFontChooser *fontchooser)
362 {
363   char *text;
364 
365   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
366 
367   g_object_get (fontchooser, "preview-text", &text, NULL);
368 
369   return text;
370 }
371 
372 /**
373  * gtk_font_chooser_set_preview_text:
374  * @fontchooser: a #GtkFontChooser
375  * @text: (transfer none): the text to display in the preview area
376  *
377  * Sets the text displayed in the preview area.
378  * The @text is used to show how the selected font looks.
379  *
380  * Since: 3.2
381  */
382 void
gtk_font_chooser_set_preview_text(GtkFontChooser * fontchooser,const gchar * text)383 gtk_font_chooser_set_preview_text (GtkFontChooser *fontchooser,
384                                    const gchar    *text)
385 {
386   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
387   g_return_if_fail (text != NULL);
388 
389   g_object_set (fontchooser, "preview-text", text, NULL);
390 }
391 
392 /**
393  * gtk_font_chooser_get_show_preview_entry:
394  * @fontchooser: a #GtkFontChooser
395  *
396  * Returns whether the preview entry is shown or not.
397  *
398  * Returns: %TRUE if the preview entry is shown
399  *     or %FALSE if it is hidden.
400  *
401  * Since: 3.2
402  */
403 gboolean
gtk_font_chooser_get_show_preview_entry(GtkFontChooser * fontchooser)404 gtk_font_chooser_get_show_preview_entry (GtkFontChooser *fontchooser)
405 {
406   gboolean show;
407 
408   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), FALSE);
409 
410   g_object_get (fontchooser, "show-preview-entry", &show, NULL);
411 
412   return show;
413 }
414 
415 /**
416  * gtk_font_chooser_set_show_preview_entry:
417  * @fontchooser: a #GtkFontChooser
418  * @show_preview_entry: whether to show the editable preview entry or not
419  *
420  * Shows or hides the editable preview entry.
421  *
422  * Since: 3.2
423  */
424 void
gtk_font_chooser_set_show_preview_entry(GtkFontChooser * fontchooser,gboolean show_preview_entry)425 gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser,
426                                          gboolean        show_preview_entry)
427 {
428   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
429 
430   show_preview_entry = show_preview_entry != FALSE;
431   g_object_set (fontchooser, "show-preview-entry", show_preview_entry, NULL);
432 }
433 
434 /**
435  * gtk_font_chooser_set_filter_func:
436  * @fontchooser: a #GtkFontChooser
437  * @filter: (allow-none): a #GtkFontFilterFunc, or %NULL
438  * @user_data: data to pass to @filter
439  * @destroy: function to call to free @data when it is no longer needed
440  *
441  * Adds a filter function that decides which fonts to display
442  * in the font chooser.
443  *
444  * Since: 3.2
445  */
446 void
gtk_font_chooser_set_filter_func(GtkFontChooser * fontchooser,GtkFontFilterFunc filter,gpointer user_data,GDestroyNotify destroy)447 gtk_font_chooser_set_filter_func (GtkFontChooser   *fontchooser,
448                                   GtkFontFilterFunc filter,
449                                   gpointer          user_data,
450                                   GDestroyNotify    destroy)
451 {
452   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
453 
454   GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->set_filter_func (fontchooser,
455                                                              filter,
456                                                              user_data,
457                                                              destroy);
458 }
459 
460 void
_gtk_font_chooser_font_activated(GtkFontChooser * chooser,const gchar * fontname)461 _gtk_font_chooser_font_activated (GtkFontChooser *chooser,
462                                   const gchar    *fontname)
463 {
464   g_return_if_fail (GTK_IS_FONT_CHOOSER (chooser));
465 
466   g_signal_emit (chooser, chooser_signals[SIGNAL_FONT_ACTIVATED], 0, fontname);
467 }
468 
469 /**
470  * gtk_font_chooser_set_font_map:
471  * @fontchooser: a #GtkFontChooser
472  * @fontmap: (allow-none): a #PangoFontMap
473  *
474  * Sets a custom font map to use for this font chooser widget.
475  * A custom font map can be used to present application-specific
476  * fonts instead of or in addition to the normal system fonts.
477  *
478  * |[<!-- language="C" -->
479  * FcConfig *config;
480  * PangoFontMap *fontmap;
481  *
482  * config = FcInitLoadConfigAndFonts ();
483  * FcConfigAppFontAddFile (config, my_app_font_file);
484  *
485  * fontmap = pango_cairo_font_map_new_for_font_type (CAIRO_FONT_TYPE_FT);
486  * pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (fontmap), config);
487  *
488  * gtk_font_chooser_set_font_map (font_chooser, fontmap);
489  * ]|
490  *
491  * Note that other GTK+ widgets will only be able to use the application-specific
492  * font if it is present in the font map they use:
493  *
494  * |[
495  * context = gtk_widget_get_pango_context (label);
496  * pango_context_set_font_map (context, fontmap);
497  * ]|
498  *
499  * Since: 3.18
500  */
501 void
gtk_font_chooser_set_font_map(GtkFontChooser * fontchooser,PangoFontMap * fontmap)502 gtk_font_chooser_set_font_map (GtkFontChooser *fontchooser,
503                                PangoFontMap   *fontmap)
504 {
505   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
506   g_return_if_fail (fontmap == NULL || PANGO_IS_FONT_MAP (fontmap));
507 
508   if (GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->set_font_map)
509     GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->set_font_map (fontchooser, fontmap);
510 }
511 
512 /**
513  * gtk_font_chooser_get_font_map:
514  * @fontchooser: a #GtkFontChooser
515  *
516  * Gets the custom font map of this font chooser widget,
517  * or %NULL if it does not have one.
518  *
519  * Returns: (nullable) (transfer full): a #PangoFontMap, or %NULL
520  *
521  * Since: 3.18
522  */
523 PangoFontMap *
gtk_font_chooser_get_font_map(GtkFontChooser * fontchooser)524 gtk_font_chooser_get_font_map (GtkFontChooser *fontchooser)
525 {
526   PangoFontMap *fontmap = NULL;
527 
528   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
529 
530   if (GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_map)
531     fontmap = GTK_FONT_CHOOSER_GET_IFACE (fontchooser)->get_font_map (fontchooser);
532 
533   return fontmap;
534 }
535 
536 /**
537  * gtk_font_chooser_set_level:
538  * @fontchooser: a #GtkFontChooser
539  * @level: the desired level of granularity
540  *
541  * Sets the desired level of granularity for selecting fonts.
542  *
543  * Since: 3.24
544  */
545 void
gtk_font_chooser_set_level(GtkFontChooser * fontchooser,GtkFontChooserLevel level)546 gtk_font_chooser_set_level (GtkFontChooser      *fontchooser,
547                             GtkFontChooserLevel  level)
548 {
549   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
550 
551   g_object_set (fontchooser, "level", level, NULL);
552 }
553 
554 /**
555  * gtk_font_chooser_get_level:
556  * @fontchooser: a #GtkFontChooser
557  *
558  * Returns the current level of granularity for selecting fonts.
559  *
560  * Returns: the current granularity level
561  *
562  * Since: 3.24
563  */
564 GtkFontChooserLevel
gtk_font_chooser_get_level(GtkFontChooser * fontchooser)565 gtk_font_chooser_get_level (GtkFontChooser *fontchooser)
566 {
567   GtkFontChooserLevel level;
568 
569   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), 0);
570 
571   g_object_get (fontchooser, "level", &level, NULL);
572 
573   return level;
574 }
575 
576 /**
577  * gtk_font_chooser_get_font_features:
578  * @fontchooser: a #GtkFontChooser
579  *
580  * Gets the currently-selected font features.
581  *
582  * Returns: the currently selected font features
583  *
584  * Since: 3.24
585  */
586 char *
gtk_font_chooser_get_font_features(GtkFontChooser * fontchooser)587 gtk_font_chooser_get_font_features (GtkFontChooser *fontchooser)
588 {
589   char *text;
590 
591   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
592 
593   g_object_get (fontchooser, "font-features", &text, NULL);
594 
595   return text;
596 }
597 
598 /**
599  * gtk_font_chooser_get_language:
600  * @fontchooser: a #GtkFontChooser
601  *
602  * Gets the language that is used for font features.
603  *
604  * Returns: the currently selected language
605  *
606  * Since: 3.24
607  */
608 char *
gtk_font_chooser_get_language(GtkFontChooser * fontchooser)609 gtk_font_chooser_get_language (GtkFontChooser *fontchooser)
610 {
611   char *text;
612 
613   g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
614 
615   g_object_get (fontchooser, "language", &text, NULL);
616 
617   return text;
618 }
619 
620 /**
621  * gtk_font_chooser_set_language:
622  * @fontchooser: a #GtkFontChooser
623  * @language: a language
624  *
625  * Sets the language to use for font features.
626  *
627  * Since: 3.24
628  */
629 void
gtk_font_chooser_set_language(GtkFontChooser * fontchooser,const char * language)630 gtk_font_chooser_set_language (GtkFontChooser *fontchooser,
631                                const char     *language)
632 {
633   g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
634 
635   g_object_set (fontchooser, "language", language, NULL);
636 }
637