1 /* -*- coding: utf-8; indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- */
2 /* vim:set fileencodings=utf-8 tabstop=4 expandtab shiftwidth=4 softtabstop=4: */
3 /**
4 * Copyright (c) 2011 PCManX Development Group <pcmanx@googlegroups.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #ifdef __GNUG__
22 #pragma implementation "cfontconfig.h"
23 #endif
24
25 #include <X11/Xft/Xft.h>
26 #include <fontconfig/fontconfig.h>
27 #include <gdk/gdkx.h>
28
29 #include "cfontconfig.h"
30
31 struct CFontPack {
32 gchar* name;
33 XftFont* font;
34 bool check;
35 };
36
CFontConfig(void)37 CFontConfig::CFontConfig(void)
38 {
39 FcInit();
40
41 FcPattern* pattern = FcPatternCreate();
42 FcConfigSubstitute(0, pattern, FcMatchPattern);
43 FcDefaultSubstitute(pattern);
44
45 FcFontSet* font_set = FcFontSetCreate();
46 FcResult result;
47 FcFontSet* patterns = FcFontSort(0, pattern, FcTrue, 0, &result);
48
49 for (int i = 0; i < patterns->nfont; i++) {
50
51 FcPattern* font_pattern = FcFontRenderPrepare(NULL, pattern, patterns->fonts[i]);
52
53 if (font_pattern) {
54 FcFontSetAdd(font_set, font_pattern);
55 }
56 }
57
58 FcFontSetSortDestroy(patterns);
59 FcPatternDestroy(pattern);
60
61 for (int i = 0; i < font_set->nfont; i++) {
62
63 FcPattern* font = FcPatternFilter(font_set->fonts[i], NULL);
64 FcChar8* family = NULL;
65
66 if (FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch) {
67
68 CFontPack* pack = new CFontPack();
69 pack->name = g_strdup((gchar*)family);
70 pack->font = NULL;
71 pack->check = false;
72 fonts.push_back(pack);
73 }
74
75 FcPatternDestroy(font);
76 }
77
78 FcFontSetDestroy(font_set);
79 }
80
~CFontConfig(void)81 CFontConfig::~CFontConfig(void)
82 {
83 Display *display = gdk_x11_get_default_xdisplay();
84
85 for (vector<CFontPack*>::iterator it = fonts.begin(); it != fonts.end(); it++) {
86
87 XftFontClose(display, (*it)->font);
88 g_free((*it)->name);
89 delete *it;
90 }
91
92 FcFini();
93 }
94
Instance(void)95 CFontConfig* CFontConfig::Instance(void)
96 {
97 static CFontConfig* instance = new CFontConfig();
98 return instance;
99 }
100
SearchFontFor(FcChar32 ucs4)101 XftFont* CFontConfig::SearchFontFor(FcChar32 ucs4)
102 {
103 Display *display = gdk_x11_get_default_xdisplay();
104 gint screen = gdk_x11_get_default_screen();
105
106 for (vector<CFontPack*>::iterator it = fonts.begin(); it != fonts.end(); it++) {
107
108 if ((*it)->check == false) {
109
110 (*it)->font = XftFontOpen(display, screen,
111 FC_FAMILY, FcTypeString, (*it)->name,
112 FC_SIZE, FcTypeDouble, (double) 16,
113 FC_WEIGHT, FcTypeInteger, FC_WEIGHT_MEDIUM,
114 FC_ANTIALIAS, FcTypeBool, FcTrue,
115 XFT_CORE, FcTypeBool, FcFalse,
116 NULL);
117 (*it)->check = true;
118 }
119
120 if (XftCharExists(display, (*it)->font, ucs4) == FcTrue) {
121 return (*it)->font;
122 }
123 }
124 return NULL;
125 }
126