1 /*$
2 Copyright (C) 2013-2020 Azel.
3
4 This file is part of AzPainter.
5
6 AzPainter 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 3 of the License, or
9 (at your option) any later version.
10
11 AzPainter 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, see <http://www.gnu.org/licenses/>.
18 $*/
19
20 /*****************************************
21 * fontconfig
22 *****************************************/
23
24 #include <fontconfig/fontconfig.h>
25
26 #include "mDef.h"
27
28 #include "mFontConfig.h"
29 #include "mFont.h"
30 #include "mStr.h"
31
32
33 /**
34 @defgroup fontconfig mFontConfig
35 @brief fontconfig ユーティリティ
36
37 @details
38 文字列は UTF-8 で指定する。
39
40 @ingroup group_lib
41
42 @{
43 @file mFontConfig.h
44
45 @struct mFontInfo
46
47 */
48
49
50 //================================
51 // sub
52 //================================
53
54
55 /** mFontInfo から FcPattern 作成 */
56
_create_fc_pattern(mFontInfo * p)57 static FcPattern *_create_fc_pattern(mFontInfo *p)
58 {
59 FcPattern *pat;
60 int weight,slant;
61
62 pat = FcPatternCreate();
63
64 //フォントファミリー
65
66 if((p->mask & MFONTINFO_MASK_FAMILY) && !mStrIsEmpty(&p->strFamily))
67 FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)p->strFamily.buf);
68 else
69 FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)"sans-serif");
70
71 //スタイル
72
73 if((p->mask & MFONTINFO_MASK_STYLE) && !mStrIsEmpty(&p->strStyle))
74 FcPatternAddString(pat, FC_STYLE, (FcChar8 *)p->strStyle.buf);
75
76 //サイズ
77
78 if(p->mask & MFONTINFO_MASK_SIZE)
79 {
80 if(p->size < 0)
81 FcPatternAddDouble(pat, FC_PIXEL_SIZE, -(p->size));
82 else
83 FcPatternAddDouble(pat, FC_SIZE, p->size);
84 }
85
86 //太さ (指定なしなら通常)
87
88 weight = FC_WEIGHT_NORMAL;
89
90 if(p->mask & MFONTINFO_MASK_WEIGHT)
91 {
92 switch(p->weight)
93 {
94 case MFONTINFO_WEIGHT_BOLD:
95 weight = FC_WEIGHT_BOLD;
96 break;
97 }
98 }
99
100 FcPatternAddInteger(pat, FC_WEIGHT, weight);
101
102 //斜体 (指定なしなら通常)
103
104 slant = FC_SLANT_ROMAN;
105
106 if(p->mask & MFONTINFO_MASK_SLANT)
107 {
108 switch(p->slant)
109 {
110 case MFONTINFO_SLANT_ITALIC:
111 slant = FC_SLANT_ITALIC;
112 break;
113 case MFONTINFO_SLANT_OBLIQUE:
114 slant = FC_SLANT_OBLIQUE;
115 break;
116 }
117 }
118
119 FcPatternAddInteger(pat, FC_SLANT, slant);
120
121 //デフォルトの構成を適用
122
123 if(!FcConfigSubstitute(NULL, pat, FcMatchPattern))
124 {
125 FcPatternDestroy(pat);
126 return NULL;
127 }
128
129 return pat;
130 }
131
132
133 //================================
134 //
135 //================================
136
137
138 /** fontconfig 初期化 */
139
mFontConfigInit(void)140 mBool mFontConfigInit(void)
141 {
142 return FcInit();
143 }
144
145 /** fontconfig 解放 */
146
mFontConfigEnd(void)147 void mFontConfigEnd(void)
148 {
149 FcFini();
150 }
151
152 /** パターンを解放 */
153
mFontConfigPatternFree(mFcPattern * pat)154 void mFontConfigPatternFree(mFcPattern *pat)
155 {
156 if(pat)
157 FcPatternDestroy(pat);
158 }
159
160 /** 指定した構成にマッチするパターン取得 */
161
mFontConfigMatch(mFontInfo * conf)162 mFcPattern *mFontConfigMatch(mFontInfo *conf)
163 {
164 FcPattern *pat,*pat_match;
165 FcResult ret;
166
167 pat = _create_fc_pattern(conf);
168 if(!pat) return NULL;
169
170 pat_match = FcFontMatch(0, pat, &ret);
171
172 FcPatternDestroy(pat);
173
174 return pat_match;
175 }
176
177 /** パターンからファイル情報取得
178 *
179 * @param file pat の領域内のポインタが返る。pat を解放するまでは有効 */
180
mFontConfigGetFileInfo(mFcPattern * pat,char ** file,int * index)181 int mFontConfigGetFileInfo(mFcPattern *pat,char **file,int *index)
182 {
183 *file = NULL;
184 *index = 0;
185
186 if(FcPatternGetString(pat, FC_FILE, 0, (FcChar8 **)file) != FcResultMatch)
187 return -1;
188
189 FcPatternGetInteger(pat, FC_INDEX, 0, index);
190
191 return 0;
192 }
193
194 /** パターンから文字列取得
195 *
196 * @return ポインタは解放しないこと。NULL で失敗。 */
197
mFontConfigGetText(mFcPattern * pat,const char * object)198 char *mFontConfigGetText(mFcPattern *pat,const char *object)
199 {
200 FcChar8 *text;
201
202 if(FcPatternGetString(pat, object, 0, &text) == FcResultMatch)
203 return (char *)text;
204 else
205 return NULL;
206 }
207
208 /** パターンから bool 値取得 */
209
mFontConfigGetBool(mFcPattern * pat,const char * object,mBool def)210 mBool mFontConfigGetBool(mFcPattern *pat,const char *object,mBool def)
211 {
212 FcBool ret;
213
214 if(FcPatternGetBool(pat, object, 0, &ret) == FcResultMatch)
215 return ret;
216 else
217 return def;
218 }
219
220 /** パターンから int 値取得 */
221
mFontConfigGetInt(mFcPattern * pat,const char * object,int def)222 int mFontConfigGetInt(mFcPattern *pat,const char *object,int def)
223 {
224 int ret;
225
226 if(FcPatternGetInteger(pat, object, 0, &ret) == FcResultMatch)
227 return ret;
228 else
229 return def;
230 }
231
232 /** パターンから double 値取得 */
233
mFontConfigGetDouble(mFcPattern * pat,const char * object,double def)234 double mFontConfigGetDouble(mFcPattern *pat,const char *object,double def)
235 {
236 double ret;
237
238 if(FcPatternGetDouble(pat, object, 0, &ret) == FcResultMatch)
239 return ret;
240 else
241 return def;
242 }
243
244 /** パターンから double 値取得 */
245
mFontConfigGetDouble2(mFcPattern * pat,const char * object,double * dst)246 mBool mFontConfigGetDouble2(mFcPattern *pat,const char *object,double *dst)
247 {
248 return (FcPatternGetDouble(pat, object, 0, dst) == FcResultMatch);
249 }
250
251 /** パターンから matrix 取得 */
252
mFontConfigGetMatrix(mFcPattern * pat,const char * object,double * matrix)253 mBool mFontConfigGetMatrix(mFcPattern *pat,const char *object,double *matrix)
254 {
255 FcMatrix *mt;
256
257 if(FcPatternGetMatrix(pat, object, 0, &mt) != FcResultMatch)
258 return FALSE;
259 else
260 {
261 matrix[0] = mt->xx;
262 matrix[1] = mt->xy;
263 matrix[2] = mt->yx;
264 matrix[3] = mt->yy;
265 return TRUE;
266 }
267 }
268
269 /** @} */
270