Cleanup: use eval as suffix
[blender.git] / source / blender / blenfont / intern / blf_dir.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup blf
22  *
23  * Manage search paths for font files.
24  */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <ft2build.h>
31
32 #include FT_FREETYPE_H
33 #include FT_GLYPH_H
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_vec_types.h"
38
39 #include "BLI_utildefines.h"
40 #include "BLI_fileops.h"
41 #include "BLI_listbase.h"
42 #include "BLI_path_util.h"
43 #include "BLI_string.h"
44 #include "BLI_threads.h"
45
46 #include "BLF_api.h"
47 #include "blf_internal_types.h"
48 #include "blf_internal.h"
49
50 static ListBase global_font_dir = {NULL, NULL};
51
52 static DirBLF *blf_dir_find(const char *path)
53 {
54   DirBLF *p;
55
56   p = global_font_dir.first;
57   while (p) {
58     if (BLI_path_cmp(p->path, path) == 0) {
59       return p;
60     }
61     p = p->next;
62   }
63   return NULL;
64 }
65
66 void BLF_dir_add(const char *path)
67 {
68   DirBLF *dir;
69
70   dir = blf_dir_find(path);
71   if (dir) { /* already in the list ? just return. */
72     return;
73   }
74
75   dir = (DirBLF *)MEM_callocN(sizeof(DirBLF), "BLF_dir_add");
76   dir->path = BLI_strdup(path);
77   BLI_addhead(&global_font_dir, dir);
78 }
79
80 void BLF_dir_rem(const char *path)
81 {
82   DirBLF *dir;
83
84   dir = blf_dir_find(path);
85   if (dir) {
86     BLI_remlink(&global_font_dir, dir);
87     MEM_freeN(dir->path);
88     MEM_freeN(dir);
89   }
90 }
91
92 char **BLF_dir_get(int *ndir)
93 {
94   DirBLF *p;
95   char **dirs;
96   char *path;
97   int i, count;
98
99   count = BLI_listbase_count(&global_font_dir);
100   if (!count) {
101     return NULL;
102   }
103
104   dirs = (char **)MEM_callocN(sizeof(char *) * count, "BLF_dir_get");
105   p = global_font_dir.first;
106   i = 0;
107   while (p) {
108     path = BLI_strdup(p->path);
109     dirs[i] = path;
110     p = p->next;
111   }
112   *ndir = i;
113   return dirs;
114 }
115
116 void BLF_dir_free(char **dirs, int count)
117 {
118   char *path;
119   int i;
120
121   for (i = 0; i < count; i++) {
122     path = dirs[i];
123     MEM_freeN(path);
124   }
125   MEM_freeN(dirs);
126 }
127
128 char *blf_dir_search(const char *file)
129 {
130   DirBLF *dir;
131   char full_path[FILE_MAX];
132   char *s = NULL;
133
134   for (dir = global_font_dir.first; dir; dir = dir->next) {
135     BLI_join_dirfile(full_path, sizeof(full_path), dir->path, file);
136     if (BLI_exists(full_path)) {
137       s = BLI_strdup(full_path);
138       break;
139     }
140   }
141
142   if (!s) {
143     /* check the current directory, why not ? */
144     if (BLI_exists(file)) {
145       s = BLI_strdup(file);
146     }
147   }
148
149   return s;
150 }
151
152 /* Some font have additional file with metrics information,
153  * in general, the extension of the file is: .afm or .pfm
154  */
155 char *blf_dir_metrics_search(const char *filename)
156 {
157   char *mfile;
158   char *s;
159
160   mfile = BLI_strdup(filename);
161   s = strrchr(mfile, '.');
162   if (s) {
163     if (BLI_strnlen(s, 4) < 4) {
164       MEM_freeN(mfile);
165       return NULL;
166     }
167     s++;
168     s[0] = 'a';
169     s[1] = 'f';
170     s[2] = 'm';
171
172     /* first check .afm */
173     if (BLI_exists(mfile)) {
174       return mfile;
175     }
176
177     /* and now check .pfm */
178     s[0] = 'p';
179
180     if (BLI_exists(mfile)) {
181       return mfile;
182     }
183   }
184   MEM_freeN(mfile);
185   return NULL;
186 }