1 // Copyright (c) Charles J. Cliffe 2 // SPDX-License-Identifier: GPL-2.0+ 3 4 #pragma once 5 6 #include <map> 7 #include <string> 8 #include <sstream> 9 #include <mutex> 10 #include <atomic> 11 #include "lodepng.h" 12 #include "wx/glcanvas.h" 13 #include "wx/filename.h" 14 #include "wx/stdpaths.h" 15 16 #include "SpinMutex.h" 17 18 class GLFontStringCache { 19 public: 20 GLFontStringCache(); 21 int drawlen; 22 int vpx, vpy; 23 int pxHeight = 0; 24 float msgWidth = 0.0f; 25 std::atomic_int gc; 26 std::vector<float> gl_vertices; 27 std::vector<float> gl_uv; 28 }; 29 30 class GLFontChar { 31 public: 32 GLFontChar(); 33 ~GLFontChar(); 34 35 void setId(int idval); 36 37 // Returns the code point of the 16bit character, supposely Unicode. 38 int getId() const; 39 40 void setXOffset(int xofs); 41 int getXOffset(); 42 43 void setYOffset(int yofs); 44 int getYOffset(); 45 46 void setX(int xpos); 47 int getX(); 48 49 void setY(int ypos); 50 int getY(); 51 52 void setWidth(int w); 53 int getWidth(); 54 55 void setHeight(int h); 56 int getHeight() const; 57 58 void setXAdvance(int xadv); 59 int getXAdvance(); 60 61 float getAspect() const; 62 63 void setIndex(unsigned int idx); 64 int getIndex() const; 65 66 private: 67 // this is the code point of the 16bit character, supposly Unicode. 68 int id; 69 int x, y, width, height; 70 int xoffset, yoffset; 71 int xadvance; 72 float aspect; 73 int index; 74 }; 75 76 77 78 class GLFont { 79 public: 80 81 enum Align { 82 GLFONT_ALIGN_LEFT, GLFONT_ALIGN_RIGHT, GLFONT_ALIGN_CENTER, GLFONT_ALIGN_TOP, GLFONT_ALIGN_BOTTOM 83 }; 84 enum GLFontSize { 85 GLFONT_SIZE12, 86 GLFONT_SIZE16, 87 GLFONT_SIZE18, 88 GLFONT_SIZE24, 89 GLFONT_SIZE27, //new 90 GLFONT_SIZE32, 91 GLFONT_SIZE36, //new 92 GLFONT_SIZE48, 93 GLFONT_SIZE64, //new 94 GLFONT_SIZE72, //new 95 GLFONT_SIZE96, //new 96 GLFONT_SIZE_MAX 97 }; 98 99 enum GLFontScale { 100 GLFONT_SCALE_NORMAL, 101 GLFONT_SCALE_MEDIUM, // x1.5 102 GLFONT_SCALE_LARGE, // x2 103 GLFONT_SCALE_MAX 104 }; 105 106 GLFont(GLFontSize size, std::wstring fontFileName); 107 ~GLFont(); 108 109 110 //Called to change the scale of the rendered fonts 111 static void setScale(GLFontScale scale); 112 113 static GLFontScale getScale(); 114 115 //Mean current scale factor: 1.0 in normal, 1.5 medium, 2.0 for large 116 static double getScaleFactor(); 117 118 //Return a valid font px height given the font size and scale factor 119 static int getScaledPx(int basicFontSize, double scaleFactor); 120 121 122 private: 123 124 std::wstring nextParam(std::wistringstream &str); 125 std::wstring getParamKey(const std::wstring& param_str); 126 std::wstring getParamValue(const std::wstring& param_str); 127 128 //Repository of all loaded fonts 129 static GLFont fonts[GLFontSize::GLFONT_SIZE_MAX]; 130 131 static std::atomic<GLFontScale> currentScale; 132 133 //load a given font file, (lazy loading) 134 void loadFontOnce(); 135 136 //private drawing font, 16 bit char version, called by Drawer object 137 void drawString(const std::wstring& str, int pxHeight, float xpos, float ypos, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx = 0, int vpy = 0, bool cacheable = false); 138 139 //private drawing font, 8 bit char version, called by Drawer object 140 void drawString(const std::string& str, int pxHeight, float xpos, float ypos, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx = 0, int vpy = 0, bool cacheable = false); 141 142 GLFontStringCache *cacheString(const std::wstring& str, int pxHeight, int vpx, int vpy); 143 void drawCacheString(GLFontStringCache *fc, float xpos, float ypos, Align hAlign, Align vAlign) const; 144 145 void doCacheGC(); 146 void clearCache(); 147 148 //force GC of all available fonts 149 static void clearAllCaches(); 150 151 float getStringWidth(const std::wstring& str, float size, float viewAspect); 152 153 //the string cache is per-front (internal font) 154 std::map<std::wstring, GLFontStringCache * > stringCache; 155 156 int lineHeight; 157 int base; 158 int imageWidth, imageHeight, pixHeight; 159 bool loaded; 160 GLFontSize fontSizeClass; 161 162 std::map<int, GLFontChar *> characters; 163 164 std::vector<float> gl_vertices; 165 std::vector<float> gl_uv; 166 167 //The font name as written in the def file. 168 std::wstring fontName; 169 170 //The full path font PNG filename 171 std::wstring imageFile; 172 173 //the real path location of the font definition file 174 std::wstring fontDefFileSource; 175 176 GLuint texId; 177 int gcCounter; 178 SpinMutex cache_busy; 179 180 public: 181 182 //Proxy class computing and caching the selection of the underlying fonts 183 //depending of the user input and requested scale for the fonts. 184 class Drawer { 185 186 private: 187 188 //result of the computation 189 int renderingFontIndex = 0; 190 191 double renderingFontScaleFactor = 1.0; 192 193 public: 194 195 Drawer(int basicFontSize, double scaleFactor); 196 197 //Public drawing font, 16 bit char version. 198 void drawString(const std::wstring& str, float xpos, float ypos, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx = 0, int vpy = 0, bool cacheable = false) const; 199 200 //Public drawing font, 8 bit char version. 201 void drawString(const std::string& str, float xpos, float ypos, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx = 0, int vpy = 0, bool cacheable = false) const; 202 203 }; //end class Drawer 204 205 //The User request a font of size requestedSize to display, with an additional 206 //optional scale factor scaleFactor. 207 static GLFont::Drawer getFont(int requestedSize, double scaleFactor = 1.0); 208 209 }; 210