.
1 /*
2 Copyright (C) 2015 Johan Mattsson
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 3 of the
7 License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 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
15 #include <stdio.h>
16 #include <glib.h>
17 #include <fontconfig/fontconfig.h>
18
19 gchar* find_font_with_property (FcConfig* fontconfig, const gchar* characters, const gchar* property) {
20 FcPattern* pattern;
21 FcCharSet* character_set;
22 FcObjectSet* font_properties;
23 FcFontSet* fonts;
24 FcPattern* font;
25 FcChar8* path;
26 gchar* result;
27 gchar* remaining_characters;
28 gunichar character;
29
30 if (fontconfig == NULL) {
31 g_warning("Font config not loaded.");
32 return NULL;
33 }
34
35 result = NULL;
36 pattern = FcPatternCreate ();
37
38 character_set = FcCharSetCreate ();
39
40 remaining_characters = (gchar*) characters;
41 while (TRUE) {
42 character = g_utf8_get_char (remaining_characters);
43
44 if (character == '\0') {
45 break;
46 }
47
48 FcCharSetAddChar(character_set, character);
49
50 remaining_characters = g_utf8_next_char (remaining_characters);
51 }
52
53 FcPatternAddCharSet (pattern, FC_CHARSET, character_set);
54 FcCharSetDestroy (character_set);
55 FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
56
57 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
58 font_properties = FcObjectSetBuild (property, NULL);
59 fonts = FcFontList (fontconfig, pattern, font_properties);
60
61 if (fonts && fonts->nfont > 0) {
62 font = fonts->fonts[0];
63 if (FcPatternGetString(font, property, 0, &path) == FcResultMatch) {
64 result = g_strdup ((gchar*) path);
65 }
66 }
67
68 if (fonts) {
69 FcFontSetDestroy(fonts);
70 }
71
72 if (pattern) {
73 FcPatternDestroy(pattern);
74 }
75
76 return result;
77 }
78
79 /** Find a fallback font for a set of characters.
80 * @return A path to the font file.
81 */
82 gchar* find_font (FcConfig* fontconfig, const gchar* characters) {
83 return find_font_with_property (fontconfig, characters, FC_FILE);
84 }
85
86 /** Find a fallback font for a set of characters.
87 * @return Family name of the font.
88 */
89 gchar* find_font_family (FcConfig* fontconfig, const gchar* characters) {
90 return find_font_with_property (fontconfig, characters, FC_FAMILY);
91 }
92
93 /** Find a font file from its family name.
94 * @param font_config fontconfig instance
95 * @param font_name name of the font
96 * @return full path to the font file
97 */
98 gchar* find_font_file (FcConfig* font_config, const gchar* font_name) {
99 const FcChar8* name;
100 FcPattern* search_pattern;
101 FcPattern* font;
102 FcChar8* file;
103 gchar* path;
104 FcObjectSet* font_properties;
105 FcFontSet* fonts;
106 int i;
107
108 if (font_config == NULL) {
109 g_warning("Font config not loaded.");
110 return NULL;
111 }
112
113 path = NULL;
114 name = font_name;
115
116 search_pattern = FcPatternCreate ();
117 FcPatternAddString (search_pattern, FC_FAMILY, name);
118 FcPatternAddBool (search_pattern, FC_SCALABLE, FcTrue);
119 FcPatternAddInteger (search_pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM);
120 FcPatternAddInteger (search_pattern, FC_SLANT, FC_SLANT_ROMAN);
121
122 font_properties = FcObjectSetBuild (FC_FILE, NULL);
123 fonts = FcFontList (font_config, search_pattern, font_properties);
124
125 if (fonts->nfont > 0) {
126 for (i = 0; i < fonts->nfont; i++) {
127 font = fonts->fonts[i];
128
129 if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
130 path = g_strdup ((gchar*) file);
131 break;
132 }
133 }
134 FcPatternDestroy (font);
135 }
136
137 FcPatternDestroy (search_pattern);
138
139 return path;
140 }
141