Thanks to visit codestin.com
Credit goes to glvis.github.io

GLVis  v4.2
Accurate and flexible finite element visualization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
font.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-443271.
4 //
5 // This file is part of the GLVis visualization tool and library. For more
6 // information and source code availability see https://glvis.org.
7 //
8 // GLVis is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include <vector>
13 
14 #include "font.hpp"
15 #include "aux_vis.hpp"
16 
17 struct vert_tex2d
18 {
19  float x, y;
20  float u, v;
21 
22  vert_tex2d(float x, float y, float u, float v)
23  : x(x), y(y), u(u), v(v) { }
24 };
25 
26 
27 const int font_scale = 64;
28 bool GlVisFont::LoadFont(const std::string& path, int font_index, int font_size)
29 {
30  if (!init)
31  {
32  return false;
33  }
34  if (font_init)
35  {
36  glDeleteTextures(1, &font_tex);
37  FT_Done_Face(face);
38  font_init = false;
39  }
40  if (FT_New_Face(library, path.c_str(), font_index, &face))
41  {
42  cout << "GlVisFont::LoadFont(): Cannot open font file: " << path << endl;
43  return false;
44  }
45  face_has_kerning = FT_HAS_KERNING(face);
46  int ppi_w, ppi_h;
47  GetAppWindow()->getDpi(ppi_w, ppi_h);
48  const bool use_fixed_ppi_h = true;
49  if (use_fixed_ppi_h)
50  {
51  double ratio = double(ppi_w)/ppi_h;
52  ppi_h = GetAppWindow()->isHighDpi() ? 192 : 96;
53  ppi_w = ratio*ppi_h + 0.5;
54 #ifdef GLVIS_DEBUG
55  cout << "Fonts use fixed ppi: " << ppi_w << " x " << ppi_h << endl;
56 #endif
57  }
58  if (FT_Set_Char_Size(face, 0, font_size*font_scale, ppi_w, ppi_h))
59  {
60  cout << "GlVisFont::LoadFont(): Cannot set font height: " << font_size
61  << " pts" << endl;
62  FT_Done_Face(face);
63  return false;
64  }
65 #ifdef GLVIS_DEBUG
66  cout << "Loaded font: " << path << ", index: " << font_index
67  << ", height: " << font_size << endl;
68 #endif
69 
70  // generate atlas
71  size_t w = 0, h = 0;
72  for (int c = 32; c < 128; c++)
73  {
74  if (FT_Load_Char(face, c, FT_LOAD_RENDER))
75  {
76  cout << "GlVisFont::LoadFont(): Cannot load glyph: " << (char) c << endl;
77  continue;
78  }
79  w += face->glyph->bitmap.width + 2;
80  if (h < size_t(face->glyph->bitmap.rows))
81  {
82  h = face->glyph->bitmap.rows;
83  }
84  }
85  tex_w = w;
86  tex_h = h + 2;
87 
88 #ifdef GLVIS_DEBUG
89  cout << "GlVisFont::LoadFont(): font texture dimensions are ("
90  << tex_w << ", " << tex_h << ")" << endl;
91 #endif
92 
93  glGenTextures(1, &font_tex);
94 
95  glActiveTexture(GL_TEXTURE0 + 1);
96  glBindTexture(GL_TEXTURE_2D, font_tex);
97  std::vector<uint8_t> zeros(tex_w * tex_h, 0);
98  GLenum alpha_internal_fmt = alpha_channel == GL_RED ? GL_R8 : GL_ALPHA;
99  glTexImage2D(GL_TEXTURE_2D, 0, alpha_internal_fmt, tex_w, tex_h, 0,
100  alpha_channel,
101  GL_UNSIGNED_BYTE, zeros.data());
102 
103  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
104  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
105 
106  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
107  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
108 
109  int x = 0;
110  for (int c = 32; c < 128; c++)
111  {
112  if (FT_Load_Char(face, c, FT_LOAD_RENDER))
113  {
114  cout << "GlVisFont::LoadFont(): Cannot load glyph: " << (char) c << endl;
115  continue;
116  }
117  FT_GlyphSlot glyph_slot = face->glyph;
118  glTexSubImage2D(GL_TEXTURE_2D,
119  0,
120  x + 1, 1,
121  glyph_slot->bitmap.width,
122  glyph_slot->bitmap.rows,
123  alpha_channel,
124  GL_UNSIGNED_BYTE,
125  glyph_slot->bitmap.buffer);
126  // To improve the rendering quality in some cases, we can utilize the
127  // 'lsb_delta' and 'rsb_delta' fields in 'glyph_slot'. These will need to
128  // be stored in the GlVisFont::glyph struct and used in the method
129  // bufferToDevice() of class CoreGLDevice and class FFGLDevice.
130  font_chars[c] =
131  {
132  (unsigned)(glyph_slot->bitmap.width + 2),
133  (unsigned)(glyph_slot->bitmap.rows + 2),
134  glyph_slot->bitmap_left,
135  glyph_slot->bitmap_top,
136  glyph_slot->advance.x / 64.f,
137  glyph_slot->advance.y / 64.f,
138  x / (float) w
139  };
140  x += glyph_slot->bitmap.width + 2;
141  }
142  font_init = true;
143  // glEnable(GL_TEXTURE_2D);
144  glActiveTexture(GL_TEXTURE0);
145  return true;
146 }
147 
148 void GlVisFont::getObjectSize(const std::string& text, int& w, int& h)
149 {
150  float pen_x = 0.f, pen_y = 0.f;
151  char prev_c = '\0';
152  int min_x = INT_MAX, max_x = INT_MIN;
153  int min_y = INT_MAX, max_y = INT_MIN;
154  for (char c : text)
155  {
156  const glyph &g = GetTexChar(c);
157  if (!g.w || !g.h) { continue; }
158  pen_x += GetKerning(prev_c, c);
159  // note: both g.w and g.h include padding of 2
160  // note: the x-direction bounds are not pixel-tight (include bear_x/adv_x)
161  // note: the y-direction bounds are pixel-tight
162  min_x = std::min(min_x, (int)floorf(pen_x));
163  max_x = std::max(max_x, (int)ceilf (pen_x + g.adv_x));
164  min_y = std::min(min_y, (int)floorf(pen_y + g.bear_y - (g.h - 2)));
165  max_y = std::max(max_y, (int)ceilf (pen_y + g.bear_y));
166  pen_x += g.adv_x;
167  pen_y += g.adv_y;
168  prev_c = c;
169  }
170  w = max_x - min_x;
171  h = max_y - min_y;
172 }
int32_t bear_y
Definition: font.hpp:32
float adv_x
Definition: font.hpp:33
float GetKerning(char cprev, char c)
Definition: font.hpp:82
bool isHighDpi() const
This property is set by createWindow().
Definition: sdl.hpp:224
SdlWindow * GetAppWindow()
Definition: aux_vis.cpp:58
uint32_t h
Definition: font.hpp:31
void getObjectSize(const std::string &text, int &w, int &h)
Get the width and height of the bounding box containing the rendered text.
Definition: font.cpp:148
const glyph & GetTexChar(char c) const
Definition: font.hpp:54
float adv_y
Definition: font.hpp:33
uint32_t w
Definition: font.hpp:31
bool LoadFont(const std::string &path, int font_index, int font_size)
Definition: font.cpp:28
void getDpi(int &wdpi, int &hdpi)
Definition: sdl.cpp:568
const int font_scale
Definition: font.cpp:27
int font_size
Definition: aux_vis.cpp:1641