FlatUI
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Enumerations Groups Pages
font_manager.h
Go to the documentation of this file.
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef FONT_MANAGER_H
16 #define FONT_MANAGER_H
17 
18 #include <set>
19 #include <sstream>
20 #include "fplbase/renderer.h"
21 #include "fplutil/mutex.h"
22 #include "flatui/font_buffer.h"
23 #include "flatui/font_util.h"
24 #include "flatui/version.h"
25 #include "flatui/internal/distance_computer.h"
26 #include "flatui/internal/glyph_cache.h"
27 #include "flatui/internal/flatui_util.h"
28 #include "flatui/internal/hb_complex_font.h"
29 #include "flatui/internal/hyphenator.h"
30 
31 #if defined(__APPLE__) || defined(__ANDROID__)
32 #define FLATUI_SYSTEM_FONT (1)
33 #endif // defined(__APPLE__) || defined(__ANDROID__)
34 
35 // Forward decls for FreeType.
36 typedef struct FT_LibraryRec_ *FT_Library;
37 typedef struct FT_GlyphSlotRec_ *FT_GlyphSlot;
38 typedef unsigned long FT_ULong;
39 
40 // Forward decls for Harfbuzz.
41 typedef const struct hb_language_impl_t *hb_language_t;
42 /// @endcond
43 
44 /// @brief Namespace for FlatUI library.
45 namespace flatui {
46 
47 /// @file
48 /// @addtogroup flatui_font_manager
49 /// @{
50 
51 /// @cond FLATUI_INTERNAL
52 // Forward decl.
53 class FaceData;
54 class FontTexture;
55 class FontBuffer;
56 class FontBufferContext;
57 class FontMetrics;
58 class WordEnumerator;
59 struct ScriptInfo;
60 /// @endcond
61 
62 /// @var kVerticesPerGlyph/kIndicesPerGlyph
63 ///
64 /// @brief The number of vertices/indices per a glyph entry.
65 const int32_t kVerticesPerGlyph = 4;
66 const int32_t kIndicesPerGlyph = 6;
67 
68 /// @var kGlyphCacheWidth
69 ///
70 /// @brief The default size of the glyph cache width.
71 const int32_t kGlyphCacheWidth = 1024;
72 
73 /// @var kGlyphCacheHeight
74 ///
75 /// @brief The default size of the glyph cache height.
76 const int32_t kGlyphCacheHeight = 1024;
77 
78 /// @var kGlyphCacheMaxSlices
79 ///
80 /// @brief The default size of the max glyph cache slices. The number of cache
81 /// slices grows up to the value.
82 const int32_t kGlyphCacheMaxSlices = 4;
83 
84 /// @var kDefaultLanguage
85 ///
86 /// @brief The default language used for a line break.
87 const char *const kDefaultLanguage = "en";
88 
89 #ifdef FLATUI_SYSTEM_FONT
90 /// @var kSystemFont
91 ///
92 /// @brief A constant to spefify loading a system font. Used with OpenFont() and
93 /// SelectFont() API
94 /// Currently the system font is supported on iOS/macOS and Android only.
95 const char *const kSystemFont = ".SystemFont";
96 static const HashedId kSystemFontId = HashId(kSystemFont);
97 #endif // FLATUI_SYSTEM_FONT
98 
99 /// @class FontManager
100 ///
101 /// @brief FontManager manages font rendering with OpenGL utilizing freetype
102 /// and harfbuzz as a glyph rendering and layout back end.
103 ///
104 /// It opens speficied OpenType/TrueType font and rasterize to OpenGL texture.
105 /// An application can use the generated texture for a text rendering.
106 ///
107 /// @warning The class is not threadsafe, it's expected to be only used from
108 /// within OpenGL rendering thread.
109 class FontManager {
110  public:
111  /// @brief The default constructor for FontManager.
112  FontManager();
113 
114  /// @brief Constructor for FontManager with a given cache size.
115  ///
116  /// @note The given size is rounded up to nearest power of 2 internally to be
117  /// used as an OpenGL texture sizes.
118  ///
119  /// @param[in] cache_size The size of the cache, in pixels as x & y values.
120  /// @param[in] max_slices The maximum number of cache slices. When a glyph
121  /// slice gets full with glyph entries, the cache allocates another slices for
122  /// more cache spaces up to the value.
123  FontManager(const mathfu::vec2i &cache_size, int32_t max_slices);
124 
125  /// @brief The destructor for FontManager.
126  ~FontManager();
127 
128  /// @brief Open a font face, TTF, OT font.
129  ///
130  /// In this version it supports only single face at a time.
131  ///
132  /// @param[in] font_name A C-string in UTF-8 format representing
133  /// the name of the font.
134  /// @return Returns `false` when failing to open font, such as
135  /// a file open error, an invalid file format etc. Returns `true`
136  /// if the font is opened successfully.
137  bool Open(const char *font_name);
138 
139  /// @brief Open a font face, TTF, OT font by FontFamily structure.
140  /// Use this version of API when opening a font with a family name, with a
141  /// font collection index etc.
142  ///
143  /// @param[in] family A FontFamily structure indicating font parameters.
144  /// @return Returns `false` when failing to open font, such as
145  /// a file open error, an invalid file format etc. Returns `true`
146  /// if the font is opened successfully.
147  bool Open(const FontFamily &family);
148 
149  /// @brief Discard a font face that has been opened via `Open()`.
150  ///
151  /// @param[in] font_name A C-string in UTF-8 format representing
152  /// the name of the font.
153  ///
154  /// @return Returns `true` if the font was closed successfully. Otherwise
155  /// it returns `false`.
156  bool Close(const char *font_name);
157 
158  /// @brief Discard a font face that has been opened via `Open()`.
159  /// Use this version of API when closeing a font opened with FontFamily.
160  ///
161  /// @param[in] family A FontFamily structure indicating font parameters.
162  ///
163  /// @return Returns `true` if the font was closed successfully. Otherwise
164  /// it returns `false`.
165  bool Close(const FontFamily &family);
166 
167  /// @brief Select the current font face. The font face will be used by a glyph
168  /// rendering.
169  ///
170  /// @note The font face needs to have been opened by `Open()`.
171  ///
172  /// @param[in] font_name A C-string in UTF-8 format representing
173  /// the name of the font.
174  ///
175  /// @return Returns `true` if the font was selected successfully. Otherwise it
176  /// returns false.
177  bool SelectFont(const char *font_name);
178 
179  /// @brief Select the current font face with a FontFamily.
180  bool SelectFont(const FontFamily &family);
181 
182  /// @brief Select the current font faces with a fallback priority.
183  ///
184  /// @param[in] font_names An array of C-string corresponding to the name of
185  /// the font. Font names in the array are stored in a priority order.
186  /// @param[in] count A count of font names in the array.
187  ///
188  /// @return Returns `true` if the fonts were selected successfully. Otherwise
189  /// it returns false.
190  bool SelectFont(const char *font_names[], int32_t count);
191 
192  /// @brief Select the current font faces with a fallback priority.
193  ///
194  /// @param[in] family_names An array of FontFamily structure that holds font
195  /// family information.
196  /// @param[in] count A count of font family in the array.
197  ///
198  /// @return Returns `true` if the fonts were selected successfully. Otherwise
199  /// it returns false.
200  bool SelectFont(const FontFamily family_names[], int32_t count);
201 
202  /// @brief Retrieve a vertex buffer for a font rendering using glyph cache.
203  ///
204  /// @param[in] text A C-string in UTF-8 format with the text for the
205  /// FontBuffer.
206  /// @param[in] length The length of the text string.
207  /// @param[in] parameters The FontBufferParameters specifying the parameters
208  /// for the FontBuffer.
209  ///
210  /// @return Returns `nullptr` if the string does not fit in the glyph cache.
211  /// When this happens, caller may flush the glyph cache with
212  /// `FlushAndUpdate()` call and re-try the `GetBuffer()` call.
213  FontBuffer *GetBuffer(const char *text, size_t length,
214  const FontBufferParameters &parameters);
215 
216  /// @brief Retrieve a vertex buffer for basic HTML rendering.
217  ///
218  /// @param[in] html A C-string in UTF-8 format with the HTML to be rendered.
219  /// Note that we support only a limited subset of HTML at the moment,
220  /// including anchors, paragraphs, and breaks.
221  /// @param[in] parameters The FontBufferParameters specifying the parameters
222  /// for the FontBuffer.
223  ///
224  /// @note call get_links() on the returned FontBuffer to receive information
225  /// on where the anchor links are located, and the linked-to addresses.
226  ///
227  /// @return Returns `nullptr` if the HTML does not fit in the glyph cache.
228  /// When this happens, caller may flush the glyph cache with
229  /// `FlushAndUpdate()` call and re-try the `GetBuffer()` call.
230  FontBuffer *GetHtmlBuffer(const char *html,
231  const FontBufferParameters &parameters);
232 
233  /// @brief Release the FonBuffer instance.
234  /// If the FontBuffer is a reference counting buffer, the API decrements the
235  /// reference count of the buffer and when it reaches 0, the buffer becomes
236  /// invalid.
237  /// If the buffer is non-reference counting buffer, the buffer is invalidated
238  /// immediately and all references to the FontBuffer with same parameters
239  /// become invalid. It is not a problem for those non-reference counting
240  /// buffers because they are expected to create/fetch a buffer each render
241  /// cycle.
242  void ReleaseBuffer(FontBuffer *buffer);
243 
244  /// @brief Optionally flush the glyph cache and update existing FontBuffer's
245  /// UV information.
246  /// The API doesn't change a reference count of buffers.
247  /// Note that current implementation references font instances and it is the
248  /// caller's responsibility not to close font files in use.
249  ///
250  /// @param[in] flush_cache set true to flush existing glyph cache contents.
251  void RemapBuffers(bool flush_cache);
252 
253  /// @return Returns `true` if a font has been loaded. Otherwise it returns
254  /// `false`.
255  bool FontLoaded() { return face_initialized_; }
256 
257  /// @brief Indicate a start of new layout pass.
258  ///
259  /// Call the API each time the user starts a layout pass.
260  ///
261  /// @note The user of the font_manager class is expected to use the class in
262  /// 2 passes: a layout pass and a render pass.
263  ///
264  /// During the layout pass, the user invokes `GetBuffer()` calls to fetch all
265  /// required glyphs into the cache. Once in the cache, the user can retrieve
266  /// the size of the strings to position them.
267  ///
268  /// Once the layout pass finishes, the user invokes `StartRenderPass()` to
269  /// upload cache images to the atlas texture, and use the texture in the
270  /// render pass. This design helps to minimize the frequency of the atlas
271  /// texture upload.
272  void StartLayoutPass();
273 
274  /// @brief Flush the existing glyph cache contents and start new layout pass.
275  ///
276  /// Call this API while in a layout pass when the glyph cache is fragmented.
277  // Returns false if the API failed to acquire a mutex when it's running in
278  // multithreaded mode. In that case, make sure the caller invokes the API
279  // repeatedly.
280  bool FlushAndUpdate() { return UpdatePass(true); }
281 
282  /// @brief Flush the existing FontBuffer in the cache.
283  ///
284  /// Call this API when FontBuffers are not used anymore.
285  void FlushLayout() {
286  for (auto it = map_buffers_.begin(); it != map_buffers_.end(); it++) {
287  // Erase only non-ref-counted buffers.
288  if (!it->first.get_ref_count_flag()) {
289  map_buffers_.erase(it);
290  }
291  }
292  }
293 
294  /// @brief Indicates a start of new render pass.
295  ///
296  /// Call the API each time the user starts a render pass.
297  // Returns false if the API failed to acquire a mutex when it's running in
298  // multithreaded mode. In that case, make sure the caller invokes the API
299  // repeatedly.
300  bool StartRenderPass() { return UpdatePass(false); }
301 
302  /// @return Returns font atlas texture.
303  ///
304  /// @param[in] slice an index indicating an atlas texture.
305  /// An index with kGlyphFormatsColor indicates that the slice is a multi
306  /// channel buffer for color glyphs.
307  fplbase::Texture *GetAtlasTexture(int32_t slice) {
308  // Note: We don't need to lock cache_mutex_ because we're just returning
309  // a GL texture in an array. No need to lock the GL thread.
310  if (!(slice & kGlyphFormatsColor)) {
311  return glyph_cache_->get_monochrome_buffer()->get_texture(slice);
312  } else {
313  return glyph_cache_->get_color_buffer()->get_texture(slice &
314  ~kGlyphFormatsColor);
315  }
316  }
317 
318  /// @brief The user can supply a size selector function to adjust glyph sizes
319  /// when storing a glyph cache entry. By doing that, multiple strings with
320  /// slightly different sizes can share the same glyph cache entry, so that the
321  /// user can reduce a total # of cached entries.
322  ///
323  /// @param[in] selector The callback argument is a request for the glyph
324  /// size in pixels. The callback should return the desired glyph size that
325  /// should be used for the glyph sizes.
326  void SetSizeSelector(std::function<int32_t(const int32_t)> selector) {
327  size_selector_.swap(selector);
328  }
329 
330  /// @param[in] locale A C-string corresponding to the of the
331  /// language defined in ISO 639 and the country code difined in ISO 3166
332  /// separated
333  /// by '-'. (e.g. 'en-US').
334  ///
335  /// @note The API sets language, script and layout direction used for
336  /// following text renderings based on the locale.
337  void SetLocale(const char *locale);
338 
339  /// @return Returns the current language setting as a std::string.
340  const char *GetLanguage() { return language_.c_str(); }
341 
342  /// @brief Set a script used for a script layout.
343  ///
344  /// @param[in] language ISO 15924 based script code. Default setting is
345  /// 'Latn' (Latin).
346  /// For more detail, refer http://unicode.org/iso15924/iso15924-codes.html
347  ///
348  void SetScript(const char *script);
349 
350  /// @brief Set a script layout direction.
351  ///
352  /// @param[in] direction Text layout direction.
353  /// TextLayoutDirectionLTR & TextLayoutDirectionRTL are supported.
354  ///
355  void SetLayoutDirection(const TextLayoutDirection direction) {
356  if (direction == kTextLayoutDirectionTTB) {
357  fplbase::LogError("TextLayoutDirectionTTB is not supported yet.");
358  return;
359  }
360 
361  layout_direction_ = direction;
362  }
363 
364  /// @brief Set up hyphenation pattern path.
365  /// Since the hyphenation pattern is different per locale, current locale
366  /// needs to be set properly for the hyphnation to work.
367  ///
368  /// @param[in] hyb_path A file path to search the hyb (dictionary files
369  /// required for the hyphenation process. On Android,
370  /// "/system/usr/hyphen-data" is the default search path.
371  ///
372  void SetupHyphenationPatternPath(const char *hyb_path) {
373  if (hyb_path != nullptr) {
374  hyb_path_ = hyb_path;
375  }
376  if (!hyphenation_rule_.empty() && !hyb_path_.empty()) {
377  std::string pattern_file =
378  hyb_path_ + "/hyph-" + hyphenation_rule_ + ".hyb";
379  hyphenator_.Open(pattern_file.c_str());
380  }
381  }
382 
383  /// @return Returns the current layout direciton.
384  TextLayoutDirection GetLayoutDirection() { return layout_direction_; }
385 
386  /// @return Returns the current font.
387  HbFont *GetCurrentFont() { return current_font_; }
388 
389  /// @brief Enable an use of color glyphs in supporting OTF/TTF font.
390  /// The API will initialize internal glyph cache for color glyphs.
391  void EnableColorGlyph();
392 
393  /// @brief Set an ellipsis string used in label/edit widgets.
394  ///
395  /// @param[in] ellipsis A C-string specifying characters used as an ellipsis.
396  /// Can be multiple characters, typically '...'. When a string in a widget
397  /// doesn't fit to the given size, the string is truncated to fit the ellipsis
398  /// string appended at the end.
399  /// @param[in] mode A flag controlling appending behavior of the ellipsis.
400  /// Default is kEllipsisModeTruncateCharacter.
401  ///
402  /// Note: FontManager doesn't support dynamic change of the ellipsis string
403  /// in current version. FontBuffer contents that has been created are not
404  /// updated when the ellipsis string is changed.
405  void SetTextEllipsis(const char *ellipsis,
406  EllipsisMode mode = kEllipsisModeTruncateCharacter) {
407  ellipsis_ = ellipsis;
408  ellipsis_mode_ = mode;
409  }
410 
411  /// @brief Check a status of the font buffer.
412  /// @param[in] font_buffer font buffer to check.
413  ///
414  /// @return Returns a status of the FontBuffer if it's ready to use with
415  /// current texture atlas contents.
416  FontBufferStatus GetFontBufferStatus(const FontBuffer &font_buffer) const;
417 
418  private:
419  // Pass indicating rendering pass.
420  static const int32_t kRenderPass = -1;
421 
422  // Initialize static data associated with the class.
423  void Initialize();
424 
425  // Clean up static data associated with the class.
426  // Note that after the call, an application needs to call Initialize() again
427  // to use the class.
428  static void Terminate();
429 
430  // Layout text and update harfbuzz_buf_.
431  // Returns the width of the text layout in pixels.
432  int32_t LayoutText(const char *text, size_t length, int32_t max_width = 0,
433  int32_t current_width = 0, bool last_line = false,
434  bool enable_hyphenation = false,
435  int32_t *rewind = nullptr);
436 
437  // Helper function to add string information to the buffer.
438  bool UpdateBuffer(const WordEnumerator &word_enum,
439  const FontBufferParameters &parameters, int32_t base_line,
440  FontBuffer *buffer, FontBufferContext *context,
441  mathfu::vec2 *pos, FontMetrics *metrics);
442 
443  // Helper function to remove entries from the buffer for specified width.
444  void RemoveEntries(const FontBufferParameters &parameters,
445  uint32_t required_width, FontBuffer *buffer,
446  FontBufferContext *context, mathfu::vec2 *pos);
447 
448  // Helper function to append ellipsis to the buffer.
449  bool AppendEllipsis(const WordEnumerator &word_enum,
450  const FontBufferParameters &parameters, int32_t base_line,
451  FontBuffer *buffer, FontBufferContext *context,
452  mathfu::vec2 *pos, FontMetrics *metrics);
453 
454  // Calculate internal/external leading value and expand a buffer if
455  // necessary.
456  // Returns true if the size of metrics has been changed.
457  bool UpdateMetrics(int32_t top, int32_t height,
458  const FontMetrics &current_metrics,
459  FontMetrics *new_metrics);
460 
461  // Retrieve cached entry from the glyph cache.
462  // If an entry is not found in the glyph cache, the API tries to create new
463  // cache entry and returns it if succeeded.
464  // Returns nullptr if,
465  // - The font doesn't have the requested glyph.
466  // - The glyph doesn't fit into the cache (even after trying to evict some
467  // glyphs in cache based on LRU rule).
468  // (e.g. Requested glyph size too large or the cache is highly fragmented.)
469  const GlyphCacheEntry *GetCachedEntry(uint32_t code_point, uint32_t y_size,
470  GlyphFlags flags);
471 
472  // Update font manager, check glyph cache if the texture atlas needs to be
473  // updated.
474  // If start_subpass == true,
475  // the API uploads the current atlas texture, flushes cache and starts
476  // a sub layout pass. Use the feature when the cache is full and needs to
477  // flushed during a rendering pass.
478  // Returns false if the API failed to acquire a mutex when it's running in
479  // multithreaded mode. In that case, make sure the caller invokes the API
480  // repeatedly.
481  bool UpdatePass(bool start_subpass);
482 
483  // Update UV value in the FontBuffer.
484  // Returns nullptr if one of UV values couldn't be updated.
485  FontBuffer *UpdateUV(GlyphFlags flags, FontBuffer *buffer);
486 
487  // Convert requested glyph size using SizeSelector if it's set.
488  int32_t ConvertSize(int32_t size);
489 
490  // Retrieve a caret count in a specific glyph from linebreak and halfbuzz
491  // glyph information.
492  int32_t GetCaretPosCount(const WordEnumerator &enumerator,
493  const hb_glyph_info_t *info, int32_t glyph_count,
494  int32_t index);
495 
496  // Create FontBuffer with requested parameters.
497  // The function may return nullptr if the glyph cache is full.
498  FontBuffer *CreateBuffer(const char *text, uint32_t length,
499  const FontBufferParameters &parameters,
500  mathfu::vec2 *text_pos = nullptr);
501 
502  // Check if the requested buffer already exist in the cache.
503  FontBuffer *FindBuffer(const FontBufferParameters &parameters);
504 
505  // Fill in the FontBuffer with the given text.
506  FontBuffer *FillBuffer(const char *text, uint32_t length,
507  const FontBufferParameters &parameters,
508  FontBuffer *buffer, FontBufferContext *context,
509  mathfu::vec2 *text_pos = nullptr);
510 
511  // Update language related settings.
512  void SetLanguageSettings();
513 
514  // Hyphenate given string and layout it.
515  int32_t Hyphenate(const char *text, size_t length, int32_t available_space,
516  int32_t *rewind);
517 
518  // Apply HtmlFontSection settings while parsing HTML text.
519  void SetFontProperties(const HtmlSection &font_section,
521 
522  // Look up a supported locale.
523  // Returns nullptr if the API doesn't find the specified locale.
524  const ScriptInfo *FindLocale(const char *locale);
525 
526  // Check if speficied language is supported in the font manager engine.
527  bool IsLanguageSupported(const char *language);
528 
529  /// @brief Set a line height for a multi-line text.
530  ///
531  /// @param[in] line_height A float representing the line height for a
532  /// multi-line text.
533  void SetLineHeightScale(float line_height_scale) {
534  line_height_scale_ = line_height_scale;
535  }
536 
537  /// @brief Set a kerning scale value.
538  ///
539  /// @param[in] kerning_scale A float representing the kerning scale value
540  /// applied to the kerning values retrieved from Harfbuzz used in the text
541  /// rendering.
542  void SetKerningScale(float kerning_scale) { kerning_scale_ = kerning_scale; }
543 
544  /// @brief Retrieve the system's font fallback list and all fonts in the
545  /// list.
546  /// The implementation is platform specific.
547  /// @return true if the system font is successfully opened.
548  bool OpenSystemFont();
549 
550  /// @brief Helper function to check font coverage.
551  /// @param[in] face FreeType face to check font coverage.
552  /// @param[out] font_coverage A set updated for the coverage map of the face.
553  /// @return true if the specified font has a new glyph entry.
554  bool UpdateFontCoverage(FT_Face face, std::set<FT_ULong> *font_coverage);
555 
556 /// @brief Platform specific implementation of a system font access.
557 #ifdef __APPLE__
558  bool OpenSystemFontApple();
559  bool CloseSystemFontApple();
560 #endif // __APPLE__
561 #ifdef __ANDROID__
562  bool OpenSystemFontAndroid();
563  bool CloseSystemFontAndroid();
564  void ReorderSystemFonts(std::vector<FontFamily> *font_list) const;
565 #endif // __ANDROID__
566 
567  /// @brief Close all fonts in the system's font fallback list opened by
568  /// OpenSystemFont().
569  bool CloseSystemFont();
570 
571  // flag indicating if a font file has loaded.
572  bool face_initialized_;
573 
574  // Map that keeps opened face data instances.
575  std::unordered_map<std::string, std::unique_ptr<FaceData>> map_faces_;
576 
577  // Used to cache font instances. Refers to memory owned by map_faces_.
578  HbFontCache font_cache_;
579 
580  // Pointer to active font face instance.
581  HbFont *current_font_;
582 
583  // Cache for a texture atlas + vertex array rendering.
584  // Using the FontBufferParameters as keys.
585  // The map is used for GetBuffer() API.
586  std::map<FontBufferParameters, std::unique_ptr<FontBuffer>,
587  FontBufferParameters> map_buffers_;
588 
589  // Singleton instance of Freetype library.
590  static FT_Library *ft_;
591 
592  // Harfbuzz buffer
593  static hb_buffer_t *harfbuzz_buf_;
594 
595  // Unique pointer to a glyph cache.
596  std::unique_ptr<GlyphCache> glyph_cache_;
597 
598  // Current atlas texture's contents revision.
599  int32_t current_atlas_revision_;
600  // A revision that the atlas texture is flushed last time.
601  int32_t atlas_last_flush_revision_;
602 
603  // Current pass counter.
604  // Current implementation only supports up to 2 passes in a rendering cycle.
605  int32_t current_pass_;
606 
607  // Size selector function object used to adjust a glyph size.
608  std::function<int32_t(const int32_t)> size_selector_;
609 
610  // Language of input strings.
611  // Used to determine line breaking depending on a language.
612  uint32_t script_;
613  std::string language_;
614  std::string locale_;
615  TextLayoutDirection layout_direction_;
616  static const ScriptInfo script_table_[];
617  static const char *language_table_[];
618  hb_language_t hb_language_;
619 
620  // Line height for a multi line text.
621  float line_height_scale_;
622  float kerning_scale_;
623 
624  // Current line width. Needs to be persistent while appending buffers.
625  int32_t line_width_;
626 
627  // Ellipsis settings.
628  std::string ellipsis_;
629  EllipsisMode ellipsis_mode_;
630 
631  // Hyphenation settings.
632  std::string hyb_path_;
633  std::string hyphenation_rule_;
634  Hyphenator hyphenator_;
635 
636  // Line break info buffer used in libunibreak.
637  std::vector<char> wordbreak_info_;
638 
639  // A buffer includes font face index of the current font's faces.
640  std::vector<int32_t> fontface_index_;
641 
642  // An instance of signed distance field generator.
643  // To avoid redundant initializations, the FontManager holds an instnce of the
644  // class.
645  DistanceComputer<uint8_t> sdf_computer_;
646 
647  // Mutex guarding glyph cache's buffer access.
648  fplutil::Mutex *cache_mutex_;
649 
650  // A font fallback list retrieved from the current system.
651  std::vector<FontFamily> system_fallback_list_;
652 
653  const FlatUIVersion *version_;
654 };
655 
656 /// @struct ScriptInfo
657 ///
658 /// @brief This struct holds the script information used for a text layout.
659 ///
660 struct ScriptInfo {
661  /// @var locale
662  /// @brief A C-string corresponding to the of the
663  /// language defined in ISO 639 and the country code difined in ISO 3166
664  /// separated
665  /// by '-'. (e.g. 'en-US').
666  const char *locale;
667 
668  /// @var script
669  /// @brief ISO 15924 Script code.
670  const char *script;
671 
672  /// @var hyphenation
673  /// @brief Hyphenation rule.
674  const char *hyphenation;
675 
676  /// @var direction
677  /// @brief Script layout direciton.
679 };
680 /// @}
681 
682 /// @class FontShader
683 ///
684 /// @brief Helper class to handle shaders for a font rendering.
685 /// The class keeps a reference to a shader, and a location of uniforms with a
686 /// fixed names.
687 /// A caller is responsive not to call set_* APIs that specified shader doesn't
688 /// support.
689 class FontShader {
690  public:
691  void set(fplbase::Shader *shader) {
692  assert(shader);
693  shader_ = shader;
694  pos_offset_ = shader->FindUniform("pos_offset");
695  color_ = shader->FindUniform("color");
696  clipping_ = shader->FindUniform("clipping");
697  threshold_ = shader->FindUniform("threshold");
698  }
699  void set_renderer(const fplbase::Renderer &renderer) {
700  shader_->Set(renderer);
701  }
702 
703  void set_position_offset(const mathfu::vec3 &vec) {
704  assert(fplbase::ValidUniformHandle(pos_offset_));
705  shader_->SetUniform(pos_offset_, vec);
706  }
707  void set_color(const mathfu::vec4 &vec) {
708  assert(fplbase::ValidUniformHandle(color_));
709  shader_->SetUniform(color_, vec);
710  }
711  void set_clipping(const mathfu::vec4 &vec) {
712  assert(fplbase::ValidUniformHandle(clipping_));
713  shader_->SetUniform(clipping_, vec);
714  }
715  void set_threshold(float f) {
716  assert(fplbase::ValidUniformHandle(threshold_));
717  shader_->SetUniform(threshold_, &f, 1);
718  }
719 
720  fplbase::UniformHandle clipping_handle() { return clipping_; }
721  fplbase::UniformHandle color_handle() { return color_; }
722  fplbase::UniformHandle position_offset_handle() { return pos_offset_; }
723  fplbase::UniformHandle threshold_handle() { return threshold_; }
724 
725  private:
726  fplbase::Shader *shader_;
727  fplbase::UniformHandle pos_offset_;
728  fplbase::UniformHandle color_;
729  fplbase::UniformHandle clipping_;
730  fplbase::UniformHandle threshold_;
731 };
732 /// @}
733 
734 } // namespace flatui
735 
736 #endif // FONT_MANAGER_H
Helper class to handle shaders for a font rendering. The class keeps a reference to a shader...
Definition: font_manager.h:689
const char * GetLanguage()
Definition: font_manager.h:340
void RemapBuffers(bool flush_cache)
Optionally flush the glyph cache and update existing FontBuffer's UV information. The API doesn't cha...
const char * hyphenation
Hyphenation rule.
Definition: font_manager.h:674
const int32_t kGlyphCacheWidth
The default size of the glyph cache width.
Definition: font_manager.h:71
const int32_t kGlyphCacheHeight
The default size of the glyph cache height.
Definition: font_manager.h:76
FontManager manages font rendering with OpenGL utilizing freetype and harfbuzz as a glyph rendering a...
Definition: font_manager.h:109
TextLayoutDirection GetLayoutDirection()
Definition: font_manager.h:384
bool SelectFont(const char *font_name)
Select the current font face. The font face will be used by a glyph rendering.
const char *const kDefaultLanguage
The default language used for a line break.
Definition: font_manager.h:87
const int32_t kIndicesPerGlyph
The number of vertices/indices per a glyph entry.
Definition: font_manager.h:66
void StartLayoutPass()
Indicate a start of new layout pass.
FontBufferStatus GetFontBufferStatus(const FontBuffer &font_buffer) const
Check a status of the font buffer.
void EnableColorGlyph()
Enable an use of color glyphs in supporting OTF/TTF font. The API will initialize internal glyph cach...
bool Close(const char *font_name)
Discard a font face that has been opened via Open().
HbFont * GetCurrentFont()
Definition: font_manager.h:387
This class that includes font buffer parameters. It is used as a key in the unordered_map to look up ...
Definition: font_buffer.h:223
bool Open(const char *font_name)
Open a font face, TTF, OT font.
FontBufferStatus
A status of FontBuffer correspoinding current glyph cache contents. Enumerations: ...
Definition: font_buffer.h:128
bool FontLoaded()
Definition: font_manager.h:255
void ReleaseBuffer(FontBuffer *buffer)
Release the FonBuffer instance. If the FontBuffer is a reference counting buffer, the API decrements ...
const int32_t kGlyphCacheMaxSlices
The default size of the max glyph cache slices. The number of cache slices grows up to the value...
Definition: font_manager.h:82
TextLayoutDirection direction
Script layout direciton.
Definition: font_manager.h:678
~FontManager()
The destructor for FontManager.
void FlushLayout()
Flush the existing FontBuffer in the cache.
Definition: font_manager.h:285
fplbase::Texture * GetAtlasTexture(int32_t slice)
Definition: font_manager.h:307
void SetLocale(const char *locale)
void SetSizeSelector(std::function< int32_t(const int32_t)> selector)
The user can supply a size selector function to adjust glyph sizes when storing a glyph cache entry...
Definition: font_manager.h:326
void SetTextEllipsis(const char *ellipsis, EllipsisMode mode=kEllipsisModeTruncateCharacter)
Set an ellipsis string used in label/edit widgets.
Definition: font_manager.h:405
FontBuffer * GetBuffer(const char *text, size_t length, const FontBufferParameters &parameters)
Retrieve a vertex buffer for a font rendering using glyph cache.
This struct holds the script information used for a text layout.
Definition: font_manager.h:660
bool StartRenderPass()
Indicates a start of new render pass.
Definition: font_manager.h:300
this is used with the texture atlas rendering.
Definition: font_buffer.h:832
A class holding font family information. The class provides various ways to support fonts such as a f...
Definition: font_buffer.h:149
Temporary buffers used while generating FontBuffer. Word boundary information. This information is us...
Definition: font_buffer.h:719
TextLayoutDirection
Specify how to layout texts. Default value is TextLayoutDirectionLTR.
Definition: font_buffer.h:75
This class has additional properties for font metrics.
Definition: font_buffer.h:474
const char *const kSystemFont
A constant to spefify loading a system font. Used with OpenFont() and SelectFont() API Currently the ...
Definition: font_manager.h:95
void SetLayoutDirection(const TextLayoutDirection direction)
Set a script layout direction.
Definition: font_manager.h:355
EllipsisMode
A flag controlling appending behavior of the ellipsis. Enumerations:
Definition: font_buffer.h:139
FontBuffer * GetHtmlBuffer(const char *html, const FontBufferParameters &parameters)
Retrieve a vertex buffer for basic HTML rendering.
const char * locale
A C-string corresponding to the of the language defined in ISO 639 and the country code difined in IS...
Definition: font_manager.h:666
const char * script
ISO 15924 Script code.
Definition: font_manager.h:670
bool FlushAndUpdate()
Flush the existing glyph cache contents and start new layout pass.
Definition: font_manager.h:280
FontManager()
The default constructor for FontManager.
void SetScript(const char *script)
Set a script used for a script layout.
void SetupHyphenationPatternPath(const char *hyb_path)
Set up hyphenation pattern path. Since the hyphenation pattern is different per locale, current locale needs to be set properly for the hyphnation to work.
Definition: font_manager.h:372