ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Util.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <FileSystem.h>
11 
12 #include <cmath>
13 
15 
16 namespace cloudViewer {
17 namespace visualization {
18 namespace gui {
19 
20 ImVec4 colorToImgui(const Color &color) {
21  return ImVec4(color.GetRed(), color.GetGreen(), color.GetBlue(),
22  color.GetAlpha());
23 }
24 
25 uint32_t colorToImguiRGBA(const Color &color) {
26  return IM_COL32(int(std::round(255.0f * color.GetRed())),
27  int(std::round(255.0f * color.GetGreen())),
28  int(std::round(255.0f * color.GetBlue())),
29  int(std::round(255.0f * color.GetAlpha())));
30 }
31 
32 std::string FindFontPath(std::string font, FontStyle style) {
33  using namespace cloudViewer::utility::filesystem;
34 
35  std::vector<std::string> kNormalSuffixes = {
36  " Regular.ttf", " Regular.ttc", " Regular.otf", " Normal.ttf",
37  " Normal.ttc", " Normal.otf", " Medium.ttf", " Medium.ttc",
38  " Medium.otf", " Narrow.ttf", " Narrow.ttc", " Narrow.otf",
39  "-Regular.ttf", "-Regular.ttc", "-Regular.otf", "-Normal.ttf",
40  "-Normal.ttc", "-Normal.otf", "-Medium.ttf", "-Medium.ttc",
41  "-Medium.otf", "-Narrow.ttf", "-Narrow.ttc", "-Narrow.otf",
42  "Regular.ttf", "-Regular.ttc", "-Regular.otf", "Normal.ttf",
43  "Normal.ttc", "Normal.otf", "Medium.ttf", "Medium.ttc",
44  "Medium.otf", "Narrow.ttf", "Narrow.ttc", "Narrow.otf"};
45 
46  std::vector<std::string> suffixes;
47  switch (style) {
48  case FontStyle::NORMAL:
49  suffixes = kNormalSuffixes;
50  break;
51  case FontStyle::BOLD:
52  suffixes = {" Bold.ttf",
53  " Bold.ttc",
54  " Bold.otf",
55  "-Bold.ttf",
56  "-Bold.ttc",
57  "-Bold.otf",
58  "Bold.ttf",
59  "Bold.ttc",
60  "Bold.oft"
61 #if _WIN32
62  ,
63  "b.ttf",
64  "b.ttc",
65  "b.otf"
66 #endif // _WIN32
67  };
68  break;
69  case FontStyle::ITALIC:
70  suffixes = {" Italic.ttf",
71  " Italic.ttc",
72  " Italic.otf",
73  "-Italic.ttf",
74  "-Italic.ttc",
75  "-Italic.otf",
76  "Italic.ttf",
77  "Italic.ttc",
78  "Italic.otf",
79  "-MediumItalic.ttf",
80  "-MediumItalic.ttc",
81  "-MediumItalic.otf",
82  "MediumItalic.ttf",
83  "MediumItalic.ttc",
84  "MediumItalic.otf",
85  "-Oblique.ttf",
86  "-Oblique.ttc",
87  "-Oblique.otf",
88  "Oblique.ttf",
89  "Oblique.ttc",
90  "Oblique.otf",
91  "-MediumOblique.ttf",
92  "-MediumOblique.ttc",
93  "-MediumOblique.otf",
94  "MediumOblique.ttf",
95  "MediumOblique.ttc",
96  "MediumOblique.otf"
97 #if _WIN32
98  ,
99  "i.ttf",
100  "i.ttc",
101  "i.otf"
102 #endif // _WIN32
103  };
104  break;
106  suffixes = {" Bold Italic.ttf",
107  " Bold Italic.ttc",
108  " Bold Italic.otf",
109  "-BoldItalic.ttf",
110  "-BoldItalic.ttc",
111  "-BoldItalic.otf",
112  "BoldItalic.ttf",
113  "BoldItalic.ttc",
114  "BoldItalic.oft"
115 #if _WIN32
116  ,
117  "bi.ttf",
118  "bi.ttc",
119  "bi.otf"
120 #endif // _WIN32
121  };
122  break;
123  }
124 
125  if (FileExists(font)) {
126  if (style == FontStyle::NORMAL) {
127  return font;
128  } else {
129  // The user provided an actual font file, not just a
130  // font name. Since we are looking for bold and/or italic,
131  // we need to "stem" the font file and attempt to look for
132  // the bold and/or italicized versions.
133  for (auto &suf : kNormalSuffixes) {
134  if (font.rfind(suf) != std::string::npos) {
135  font = font.substr(0, font.size() - suf.size());
136  break;
137  }
138  }
139  // The font name doesn't have any of the suffixes,
140  // so just remove the extension
141  font = font.substr(0, font.size() - 4);
142 
143  // Check if any of the stylized suffixes work
144  for (auto &suf : suffixes) {
145  std::string candidate = font + suf;
146  if (FileExists(candidate)) {
147  return candidate;
148  }
149  }
150  // Otherwise fail
151  return "";
152  }
153  }
154 
155  std::string home;
156  char *raw_home = getenv("HOME");
157  if (raw_home) { // std::string(nullptr) is undefined
158  home = raw_home;
159  }
160  std::vector<std::string> system_font_paths = {
161 #ifdef __APPLE__
162  "/System/Library/Fonts", "/Library/Fonts", home + "/Library/Fonts"
163 #elif _WIN32
164  "c:/Windows/Fonts"
165 #else
166  "/usr/share/fonts",
167  home + "/.fonts",
168 #endif // __APPLE__
169  };
170 
171 #ifdef __APPLE__
172  std::vector<std::string> font_ext = {".ttf", ".ttc", ".otf"};
173  for (auto &font_path : system_font_paths) {
174  if (style == FontStyle::NORMAL) {
175  for (auto &ext : font_ext) {
176  std::string candidate = font_path + "/" + font + ext;
177  if (FileExists(candidate)) {
178  return candidate;
179  }
180  }
181  }
182  }
183  for (auto &font_path : system_font_paths) {
184  for (auto &suf : suffixes) {
185  std::string candidate = font_path + "/" + font + suf;
186  if (FileExists(candidate)) {
187  return candidate;
188  }
189  }
190  }
191  return "";
192 #else
193  std::string font_ttf = font + ".ttf";
194  std::string font_ttc = font + ".ttc";
195  std::string font_otf = font + ".otf";
196  auto is_match = [font, &font_ttf, &font_ttc,
197  &font_otf](const std::string &path) {
200  if (ext != "ttf" && ext != "ttc" && ext != "otf") {
201  return false;
202  }
203  if (filename == font_ttf || filename == font_ttc ||
204  filename == font_otf) {
205  return true;
206  }
207  if (filename.find(font) == 0) {
208  return true;
209  }
210  return false;
211  };
212 
213  for (auto &font_dir : system_font_paths) {
214  auto matches = FindFilesRecursively(font_dir, is_match);
215  if (style == FontStyle::NORMAL) {
216  for (auto &m : matches) {
218  GetFileNameWithoutDirectory(m)) == font) {
219  return m;
220  }
221  }
222  }
223  for (auto &m : matches) {
224  auto dir = GetFileParentDirectory(m); // has trailing slash
225  for (auto &suf : suffixes) {
226  std::string candidate = dir + font + suf;
227  if (m == candidate) {
228  return candidate;
229  }
230  }
231  }
232  }
233  return "";
234 #endif // __APPLE__
235 }
236 
237 } // namespace gui
238 } // namespace visualization
239 } // namespace cloudViewer
std::string filename
math::float4 color
static const std::string path
Definition: PointCloud.cpp:59
std::vector< std::string > FindFilesRecursively(const std::string &directory, std::function< bool(const std::string &)> is_match)
Definition: FileSystem.cpp:586
std::string GetFileParentDirectory(const std::string &filename)
Definition: FileSystem.cpp:314
std::string GetFileNameWithoutExtension(const std::string &filename)
Definition: FileSystem.cpp:295
std::string GetFileExtensionInLowerCase(const std::string &filename)
Definition: FileSystem.cpp:281
bool FileExists(const std::string &filename)
Definition: FileSystem.cpp:524
std::string GetFileNameWithoutDirectory(const std::string &filename)
Definition: FileSystem.cpp:301
uint32_t colorToImguiRGBA(const Color &color)
Definition: Util.cpp:25
std::string FindFontPath(std::string font, FontStyle style)
Definition: Util.cpp:32
ImVec4 colorToImgui(const Color &color)
Definition: Util.cpp:20
Generic file read and write utility for python interface.