Cleanup: Return early in some curve functions
[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_fileops.h"
40 #include "BLI_listbase.h"
41 #include "BLI_path_util.h"
42 #include "BLI_string.h"
43 #include "BLI_threads.h"
44 #include "BLI_utildefines.h"
45
46 #include "BLF_api.h"
47 #include "blf_internal.h"
48 #include "blf_internal_types.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   for (int i = 0; i < count; i++) {
119     char *path = dirs[i];
120     MEM_freeN(path);
121   }
122   MEM_freeN(dirs);
123 }
124
125 char *blf_dir_search(const char *file)
126 {
127   DirBLF *dir;
128   char full_path[FILE_MAX];
129   char *s = NULL;
130
131   for (dir = global_font_dir.first; dir; dir = dir->next) {
132     BLI_join_dirfile(full_path, sizeof(full_path), dir->path, file);
133     if (BLI_exists(full_path)) {
134       s = BLI_strdup(full_path);
135       break;
136     }
137   }
138
139   if (!s) {
140     /* check the current directory, why not ? */
141     if (BLI_exists(file)) {
142       s = BLI_strdup(file);
143     }
144   }
145
146   return s;
147 }
148
149 /* Some font have additional file with metrics information,
150  * in general, the extension of the file is: .afm or .pfm
151  */
152 char *blf_dir_metrics_search(const char *filename)
153 {
154   char *mfile;
155   char *s;
156
157   mfile = BLI_strdup(filename);
158   s = strrchr(mfile, '.');
159   if (s) {
160     if (BLI_strnlen(s, 4) < 4) {
161       MEM_freeN(mfile);
162       return NULL;
163     }
164     s++;
165     s[0] = 'a';
166     s[1] = 'f';
167     s[2] = 'm';
168
169     /* first check .afm */
170     if (BLI_exists(mfile)) {
171       return mfile;
172     }
173
174     /* and now check .pfm */
175     s[0] = 'p';
176
177     if (BLI_exists(mfile)) {
178       return mfile;
179     }
180   }
181   MEM_freeN(mfile);
182   return NULL;
183 }