Advertisement
Kitomas

font.cpp as of 2023-11-16

Nov 17th, 2023
692
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.35 KB | None | 0 0
  1. #include <utils/font.hpp>
  2.  
  3.  
  4. //this is where the actual default font data is
  5. #define _UTILS_FONT_CPP
  6. #include <utils/_font_tables.h>
  7. #undef _UTILS_FONT_CPP
  8.  
  9.  
  10.  
  11.  
  12. font8x8::font8x8(SDL_Renderer* renderer,
  13.                  SDL_Color background,
  14.                  SDL_Color text,
  15.                  const Uint8* table)
  16. {
  17.   if(renderer == nullptr) throw "renderer = nullptr";
  18.   if(table == nullptr) throw "table = nullptr";
  19.   _renderer = renderer;
  20.  
  21.   //8-bit indexed, though only the first 2 palette colors are used
  22.    //(also, for 128 8x8 chars, a surface size of 128x64 is used)
  23.   _fontSurface = SDL_CreateRGBSurfaceWithFormat(0,128,64,8,SDL_PIXELFORMAT_INDEX8);
  24.   if(_fontSurface == nullptr){
  25.     throw SDL_GetError(); //(_valid should already be false at this point)
  26.   }
  27.  
  28.  
  29.   //generate pixel data from font data
  30.   if(SDL_LockSurface(_fontSurface)){ //make sure i have safe access to pixel data
  31.     _freeSurfaceSafely();
  32.     throw SDL_GetError();
  33.   }
  34.  
  35.   Uint8* table_copy = (Uint8*) table; //otherwise i can't increment the pointer
  36.   Uint8* pixels = (Uint8*) _fontSurface->pixels;
  37.  
  38.   for(int yi=0; yi<64; yi+=8){ //for each char vertically
  39.     for(int xi=0; xi<128; xi+=8){ //for each char horizontally
  40.       int charPos = xi + yi*128;
  41.       for(int ri=0; ri<8; ++ri){ //for each row in current char
  42.         Uint8 row = *(table_copy++);
  43.         int rowPos = charPos + ri*128;
  44.         pixels[rowPos++] = (row>>0)&1; //each byte is a char's row (8 pixels)
  45.         pixels[rowPos++] = (row>>1)&1;
  46.         pixels[rowPos++] = (row>>2)&1;
  47.         pixels[rowPos++] = (row>>3)&1;
  48.         pixels[rowPos++] = (row>>4)&1;
  49.         pixels[rowPos++] = (row>>5)&1;
  50.         pixels[rowPos++] = (row>>6)&1;
  51.         pixels[rowPos++] = (row>>7)&1;
  52.       }
  53.     }
  54.   }
  55.  
  56.   SDL_UnlockSurface(_fontSurface); //can't error
  57.  
  58.  
  59.   //initialize palette to a user-defined color, and create font texture
  60.   _valid = SDL_TRUE; //(_valid will be set back to false if setPalette fails)
  61.   setPalette( background, text );
  62. }
  63.  
  64.  
  65.  
  66.  
  67. void font8x8::setPalette(SDL_Color background, SDL_Color text){
  68.   if(!_valid) throw "invalid font";
  69.   //the texture has be remade once the palette colors are modified
  70.   _freeTextureSafely();
  71.  
  72.   //out of the 256 possible palette colors for 8-bit indexed, i'm only using 2
  73.   _palette[0] = background;
  74.   _palette[1] = text;
  75.  
  76.  
  77.   if(SDL_LockSurface(_fontSurface)){
  78.     _freeSurfaceSafely();
  79.     _valid = SDL_FALSE;
  80.     throw SDL_GetError();
  81.   }
  82.  
  83.   //'replace 2 palette colors, starting at index 0'
  84.   if(SDL_SetPaletteColors(_fontSurface->format->palette, _palette, 0, 2)){
  85.     _freeSurfaceSafely();
  86.     _valid = SDL_FALSE;
  87.     throw SDL_GetError();
  88.   }
  89.  
  90.   SDL_UnlockSurface(_fontSurface); //can't error
  91.  
  92.  
  93.   _fontTexture = SDL_CreateTextureFromSurface(_renderer, _fontSurface);
  94.   if(_fontTexture == nullptr){
  95.     _valid = SDL_FALSE;
  96.     throw SDL_GetError();
  97.   }
  98. }
  99.  
  100.  
  101.  
  102.  
  103. void font8x8::putCharRaw(char chr, int x, int y){
  104.   if(!_valid) throw "invalid font";
  105.   //char 127 is treated as 'transparent', so don't draw anything
  106.   if((chr&=127) == 127) return;
  107.  
  108.   SDL_Rect sourceRect;
  109.  
  110.   //position inside the font sprite sheet thing
  111.   sourceRect.x = (chr&15)*8; //for a total of 16 columns, scaled by 8 pixels
  112.   sourceRect.y = (chr>>4)*8; //for a total of 8 rows, scaled by 8 pixels
  113.   sourceRect.w = 8; //source texture area should always be 8x8
  114.   sourceRect.h = 8;
  115.  
  116.   //position with regard to the render target (usually the window itself)
  117.   _lastChar.x = x;
  118.   _lastChar.y = y;
  119.   //_lastChar.<w/h> is in a union with _scale.<x/y>...
  120.   //_lastChar.w = _scale.x; ...therefore this is redundant
  121.   //_lastChar.h = _scale.y;
  122.  
  123.   SDL_RenderCopy(_renderer, _fontTexture, &sourceRect, &_lastChar);
  124. }
  125.  
  126.  
  127.  
  128.  
  129. void font8x8::printRaw(const std::string& txt, int x, int y){
  130.   if(!_valid) throw "invalid font";
  131.   int startX = x; //used for newline chars
  132.   size_t length = txt.length();
  133.  
  134.  
  135.   for(size_t i=0; i<length; ++i){
  136.     char chr = txt.at(i)&127;
  137.  
  138.     switch(chr){
  139.     //move back by 1 char
  140.     case '\b': x -= _scale.x; break;
  141.  
  142.     //reset x, AND move down by 1 char
  143.     case '\n': x  =   startX; SDL_FALLTHROUGH;
  144.     //move down by 1 char
  145.     case '\f': y += _scale.y; break;
  146.  
  147.     //move up by 1 char
  148.     case '\r': y -= _scale.y; break;
  149.  
  150.     //draw char normally
  151.     default:
  152.       putCharRaw(chr, x,y);
  153.       x += _scale.x;
  154.     }
  155.  
  156.   }
  157. }
  158.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement