ClangFormat: apply to source, most of intern
[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     p = p->next;
61   }
62   return NULL;
63 }
64
65 void BLF_dir_add(const char *path)
66 {
67   DirBLF *dir;
68
69   dir = blf_dir_find(path);
70   if (dir) /* already in the list ? just return. */
71     return;
72
73   dir = (DirBLF *)MEM_callocN(sizeof(DirBLF), "BLF_dir_add");
74   dir->path = BLI_strdup(path);
75   BLI_addhead(&global_font_dir, dir);
76 }
77
78 void BLF_dir_rem(const char *path)
79 {
80   DirBLF *dir;
81
82   dir = blf_dir_find(path);
83   if (dir) {
84     BLI_remlink(&global_font_dir, dir);
85     MEM_freeN(dir->path);
86     MEM_freeN(dir);
87   }
88 }
89
90 char **BLF_dir_get(int *ndir)
91 {
92   DirBLF *p;
93   char **dirs;
94   char *path;
95   int i, count;
96
97   count = BLI_listbase_count(&global_font_dir);
98   if (!count)
99     return NULL;
100
101   dirs = (char **)MEM_callocN(sizeof(char *) * count, "BLF_dir_get");
102   p = global_font_dir.first;
103   i = 0;
104   while (p) {
105     path = BLI_strdup(p->path);
106     dirs[i] = path;
107     p = p->next;
108   }
109   *ndir = i;
110   return dirs;
111 }
112
113 void BLF_dir_free(char **dirs, int count)
114 {
115   char *path;
116   int i;
117
118   for (i = 0; i < count; i++) {
119     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   return s;
146 }
147
148 /* Some font have additional file with metrics information,
149  * in general, the extension of the file is: .afm or .pfm
150  */
151 char *blf_dir_metrics_search(const char *filename)
152 {
153   char *mfile;
154   char *s;
155
156   mfile = BLI_strdup(filename);
157   s = strrchr(mfile, '.');
158   if (s) {
159     if (BLI_strnlen(s, 4) < 4) {
160       MEM_freeN(mfile);
161       return NULL;
162     }
163     s++;
164     s[0] = 'a';
165     s[1] = 'f';
166     s[2] = 'm';
167
168     /* first check .afm */
169     if (BLI_exists(mfile))
170       return mfile;
171
172     /* and now check .pfm */
173     s[0] = 'p';
174
175     if (BLI_exists(mfile))
176       return mfile;
177   }
178   MEM_freeN(mfile);
179   return NULL;
180 }