LCOV - code coverage report
Current view: top level - engine/render - renderttf.cpp (source / functions) Coverage Total Hit
Test: Libprimis Test Coverage Lines: 0.0 % 86 0
Test Date: 2026-06-16 06:16:16 Functions: 0.0 % 8 0

            Line data    Source code
       1              : /**
       2              :  * @file renderttf.cpp
       3              :  * @brief SDL2_TTF text renderer
       4              :  *
       5              :  * This file implements the wrapper functions needed to use SDL_TTF in the applications
       6              :  * where Tessfont/rendertext.cpp would have been used, allowing for any TTF font and
       7              :  * any Unicode character to be renderered at any font size, which are all limitations
       8              :  * of the legacy Tessfont font sampling system.
       9              :  *
      10              :  */
      11              : #include "SDL_ttf.h"
      12              : 
      13              : #include "../libprimis-headers/cube.h"
      14              : #include "../../shared/geomexts.h"
      15              : #include "../../shared/glemu.h"
      16              : #include "../../shared/glexts.h"
      17              : 
      18              : #include "rendergl.h"
      19              : #include "rendertext.h"
      20              : #include "renderttf.h"
      21              : #include "shader.h"
      22              : #include "shaderparam.h"
      23              : #include "texture.h"
      24              : #include "renderwindow.h"
      25              : 
      26              : TTFRenderer ttr;
      27              : 
      28            0 : bool TTFRenderer::initttf()
      29              : {
      30            0 :     if(TTF_Init() < 0)
      31              :     {
      32            0 :         return false;
      33              :     }
      34            0 :     return true;
      35              : }
      36              : 
      37            0 : void TTFRenderer::openfont(const char * inpath, int size)
      38              : {
      39            0 :     f = TTF_OpenFont(inpath, size);
      40            0 :     TTF_SetFontStyle(f, TTF_STYLE_NORMAL);
      41            0 :     TTF_SetFontOutline(f, 0);
      42            0 :     TTF_SetFontKerning(f, 1);
      43            0 :     TTF_SetFontHinting(f, TTF_HINTING_NORMAL);
      44            0 :     fontcache[size] = f;
      45            0 :     path = inpath;
      46            0 : }
      47              : 
      48            0 : std::string TTFRenderer::trimstring(std::string msg)
      49              : {
      50              :     for(;;)
      51              :     {
      52            0 :         size_t itr = msg.find("^f");
      53            0 :         if(itr < msg.size())
      54              :         {
      55            0 :             msg.erase(itr, 3);
      56              :         }
      57              :         else
      58              :         {
      59            0 :             break;
      60              :         }
      61            0 :     }
      62            0 :     return msg;
      63              : }
      64              : 
      65            0 : void TTFRenderer::renderttf(const char* message, SDL_Color col, int x, int y, float scale, uint wrap) const
      66              : {
      67            0 :     std::string msg = std::string(message);
      68              : 
      69            0 :     if(!msg.size())
      70              :     {
      71            0 :         return;
      72              :     }
      73              : 
      74            0 :     msg = trimstring(msg);
      75              : 
      76            0 :     TTFSurface tex = renderttfgl(msg.c_str(), col, wrap);
      77            0 :     if(tex.tex)
      78              :     {
      79            0 :         const float w = tex.w*scale,
      80            0 :                     h = tex.h*scale;
      81            0 :         SETSHADER(hudrect);
      82            0 :         gle::colorf(1, 1, 1, 1);
      83            0 :         const int tw = tex.w,
      84            0 :                   th = tex.h;
      85            0 :         gle::defvertex(2);
      86            0 :         gle::deftexcoord0();
      87            0 :         gle::begin(GL_TRIANGLE_STRIP);
      88            0 :         gle::attribf(x+w, y);  gle::attribf(tw, 0);
      89            0 :         gle::attribf(x, y);    gle::attribf(0, 0);
      90            0 :         gle::attribf(x+w,y+h); gle::attribf(tw, th);
      91            0 :         gle::attribf(x,y+h);   gle::attribf(0, th);
      92            0 :         gle::end();
      93              :         //clean up
      94            0 :         hudshader->set();
      95            0 :         glDeleteTextures(1, &(tex.tex));
      96              :     }
      97              :     else
      98              :     {
      99            0 :         printf("failed to render text:  %s\n", message);
     100              :     }
     101            0 : }
     102              : 
     103            0 : void TTFRenderer::ttfbounds(std::string_view str, float &width, float &height, int pts)
     104              : {
     105            0 :     fontsize(pts);
     106            0 :     ivec2 size = ttfsize(str);
     107            0 :     width = size.x();
     108            0 :     height = size.y();
     109            0 : }
     110              : 
     111            0 : ivec2 TTFRenderer::ttfsize(std::string_view message)
     112              : {
     113            0 :     if(!std::strlen(message.data()))
     114              :     {
     115            0 :         return ivec2(0,0);
     116              :     }
     117            0 :     std::string msg = trimstring(std::string(message));
     118              :     int x, y;
     119            0 :     TTF_SizeUTF8(f, msg.c_str(), &x, &y);
     120            0 :     return ivec2(x,y);
     121            0 : }
     122              : 
     123            0 : TTFRenderer::TTFSurface TTFRenderer::renderttfgl(const char* message, SDL_Color col, uint wrap) const
     124              : {
     125            0 :     if(!message)
     126              :     {
     127            0 :         return {0, 0, 0};
     128              :     }
     129            0 :     SDL_Color rgbcol = {col.b, col.g, col.r, 0};
     130            0 :     SDL_Surface* text = TTF_RenderUTF8_Blended_Wrapped(f, message, rgbcol, wrap);
     131              :     TTFSurface tts;
     132            0 :     if(text)
     133              :     {
     134            0 :         GLuint tex = 0;
     135            0 :         glEnable(GL_BLEND);
     136            0 :         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     137            0 :         glGenTextures(1, &tex);
     138            0 :         glBindTexture(GL_TEXTURE_RECTANGLE, tex);
     139              :         //need to load it in reversed because of how SDL_ttf renders
     140            0 :         glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, text->pitch/4, text->h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, text->pixels);
     141            0 :         tts = {tex, text->w, text->h};
     142              :     }
     143              :     else //empty string may cause this
     144              :     {
     145            0 :         tts = {0, 0, 0};
     146              :     }
     147            0 :     SDL_FreeSurface(text);
     148            0 :     return tts;
     149              : }
     150              : 
     151            0 : void TTFRenderer::fontsize(int pts)
     152              : {
     153            0 :     std::map<int, TTF_Font *>::iterator itr = fontcache.find(pts);
     154            0 :     if(itr == fontcache.end())
     155              :     {
     156            0 :         TTF_Font* newfont = TTF_OpenFont(path, pts);
     157            0 :         TTF_SetFontStyle(newfont, TTF_STYLE_NORMAL);
     158            0 :         TTF_SetFontOutline(newfont, 0);
     159            0 :         TTF_SetFontKerning(newfont, 1);
     160            0 :         TTF_SetFontHinting(newfont, TTF_HINTING_NORMAL);
     161            0 :         fontcache[pts] = newfont;
     162            0 :         f = newfont;
     163              :     }
     164              :     else
     165              :     {
     166            0 :         f = fontcache[pts];
     167              :     }
     168            0 : }
        

Generated by: LCOV version 2.0-1