Loading

Paste #pd7bmlckx

  1. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
  2. index a378245..a756c06 100644
  3. --- a/src/CMakeLists.txt
  4. +++ b/src/CMakeLists.txt
  5. @@ -85,11 +85,10 @@ IF(SDL2_FOUND)
  6.     target_link_libraries(freerct ${SDL2_LIBRARY})
  7.  ENDIF()
  8.  
  9. -find_package(SDL2_ttf REQUIRED)
  10. -# Legacy variable names
  11. -IF(SDL2_TTF_FOUND)
  12. -   include_directories(${SDL2TTF_INCLUDE_DIR})
  13. -   target_link_libraries(freerct ${SDL2TTF_LIBRARY})
  14. +find_package(Freetype REQUIRED)
  15. +IF(FREETYPE_FOUND)
  16. +   include_directories(${FREETYPE_INCLUDE_DIRS})
  17. +   target_link_libraries(freerct ${FREETYPE_LIBRARIES})
  18.  ENDIF()
  19.  
  20.  # Translated messages are bad
  21. diff --git a/src/sprite_store.cpp b/src/sprite_store.cpp
  22. index ecdb06e..acc8489 100644
  23. --- a/src/sprite_store.cpp
  24. +++ b/src/sprite_store.cpp
  25. @@ -1750,4 +1750,3 @@ PathStatus SpriteManager::GetPathStatus(PathType path_type)
  26.     const Path &path = this->store.path_sprites[path_type];
  27.     return path.status;
  28.  }
  29. -
  30. diff --git a/src/video.cpp b/src/video.cpp
  31. index e87e2f4..2feaec0 100644
  32. --- a/src/video.cpp
  33. +++ b/src/video.cpp
  34. @@ -198,29 +198,18 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size)
  35.  
  36.     SDL_StartTextInput(); // Enable Unicode character input.
  37.  
  38. -   if (TTF_Init() != 0) {
  39. -       SDL_Quit();
  40. -       delete[] this->mem;
  41. -       std::string err = "TTF font initialization failed: ";
  42. -       err += TTF_GetError();
  43. -       return err;
  44. +   /* Freetype init */
  45. +   if (FT_Init_FreeType(&this->library) != 0) {
  46.     }
  47.  
  48. -   this->font = TTF_OpenFont(font_name, font_size);
  49. -   if (this->font == nullptr) {
  50. -       std::string err = "TTF Opening font \"";
  51. -       err += font_name;
  52. -       err += "\" size ";
  53. -       err += std::to_string(font_size);
  54. -       err += " failed: ";
  55. -       err += TTF_GetError();
  56. -       TTF_Quit();
  57. -       SDL_Quit();
  58. -       delete[] this->mem;
  59. -       return err;
  60. +   if (FT_New_Face(this->library, font_name, 0, &this->face) != 0) {
  61.     }
  62.  
  63. -   this->font_height = TTF_FontLineSkip(this->font);
  64. +   /** @todo use actual screen dpi? */
  65. +   if (FT_Set_Char_Size(this->face, 0, font_size * 64, 0, 0) != 0) {
  66. +   }
  67. +
  68. +   this->font_height = this->face->height / 64;
  69.     this->initialized = true;
  70.     this->dirty = true; // Ensure it gets painted.
  71.     this->missing_sprites = false;
  72. @@ -486,8 +475,8 @@ void VideoSystem::MainLoop()
  73.  void VideoSystem::Shutdown()
  74.  {
  75.     if (this->initialized) {
  76. -       TTF_CloseFont(this->font);
  77. -       TTF_Quit();
  78. +       FT_Done_Face(this->face);
  79. +       FT_Done_FreeType(this->library);
  80.         SDL_Quit();
  81.         delete[] this->mem;
  82.         this->initialized = false;
  83. @@ -714,6 +703,52 @@ void VideoSystem::BlitImages(const Point32 &pt, const ImageData *spr, uint16 num
  84.  }
  85.  
  86.  /**
  87. + * Decode an UTF-8 character.
  88. + * @param data Pointer to the start of the data.
  89. + * @param length Length of the \a data buffer.
  90. + * @param[out] codepoint If decoding was successful, the value of the decoded character.
  91. + * @return Number of bytes read to decode the character, or \c 0 if reading failed.
  92. + */
  93. +static int DecodeUtf8Char(const uint8 *data, size_t length, uint32 *codepoint)
  94. +{
  95. +   if (length < 1) return 0;
  96. +   uint32 value = *data;
  97. +   data++;
  98. +   if ((value & 0x80) == 0) {
  99. +       *codepoint = value;
  100. +       return 1;
  101. +   }
  102. +   int size;
  103. +   uint32 min_value;
  104. +   if ((value & 0xE0) == 0xC0) {
  105. +       size = 2;
  106. +       min_value = 0x80;
  107. +       value &= 0x1F;
  108. +   } else if ((value & 0xF0) == 0xE0) {
  109. +       size = 3;
  110. +       min_value = 0x800;
  111. +       value &= 0x0F;
  112. +   } else if ((value & 0xF8) == 0xF0) {
  113. +       size = 4;
  114. +       min_value = 0x10000;
  115. +       value &= 0x07;
  116. +   } else {
  117. +       return 0;
  118. +   }
  119. +
  120. +   if (length < static_cast<size_t>(size)) return 0;
  121. +   for (int n = 1; n < size; n++) {
  122. +       uint8 val = *data;
  123. +       data++;
  124. +       if ((val & 0xC0) != 0x80) return 0;
  125. +       value = (value << 6) | (val & 0x3F);
  126. +   }
  127. +   if (value < min_value || (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) return 0;
  128. +   *codepoint = value;
  129. +   return size;
  130. +}
  131. +
  132. +/**
  133.   * Get the text-size of a string.
  134.   * @param text Text to calculate.
  135.   * @param width [out] Resulting width.
  136. @@ -721,9 +756,34 @@ void VideoSystem::BlitImages(const Point32 &pt, const ImageData *spr, uint16 num
  137.   */
  138.  void VideoSystem::GetTextSize(const uint8 *text, int *width, int *height)
  139.  {
  140. -   if (TTF_SizeUTF8(this->font, (const char *)text, width, height) != 0) {
  141. -       *width = 0;
  142. -       *height = 0;
  143. +   *width = 0;
  144. +   *height = 0;
  145. +
  146. +   bool use_kerning = FT_HAS_KERNING(this->face);
  147. +   uint previous = 0;
  148. +   FT_GlyphSlot slot = this->face->glyph;
  149. +
  150. +   for (const uint8 *pt = text; *pt != '\0';) {
  151. +       uint32 u32;
  152. +       int len = DecodeUtf8Char(pt, strlen((const char *)pt), &u32);
  153. +       if (len == 0) break;
  154. +       pt += len;
  155. +
  156. +       uint glyph = FT_Get_Char_Index(this->face, u32);
  157. +
  158. +       if (use_kerning && previous && glyph) {
  159. +           FT_Vector delta;
  160. +           FT_Get_Kerning(this->face, previous, glyph, FT_KERNING_DEFAULT, &delta);
  161. +
  162. +           *width += delta.x / 64;
  163. +       }
  164. +
  165. +       if (FT_Load_Glyph(this->face, glyph, FT_LOAD_RENDER) != 0) {
  166. +       }
  167. +       *width += slot->advance.x / 64;
  168. +       *height = std::max(*height, (int)slot->metrics.height / 64);
  169. +
  170. +       previous = glyph;
  171.     }
  172.  }
  173.  
  174. @@ -776,19 +836,12 @@ void VideoSystem::GetNumberRangeSize(int64 smallest, int64 biggest, int *width,
  175.   */
  176.  void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width, Alignment align)
  177.  {
  178. -   SDL_Color col = {0, 0, 0}; // Font colour does not matter as only the bitmap is used.
  179. -   SDL_Surface *surf = TTF_RenderUTF8_Solid(this->font, (const char *)text, col);
  180. -   if (surf == nullptr) {
  181. -       fprintf(stderr, "Rendering text failed (%s)\n", TTF_GetError());
  182. -       return;
  183. -   }
  184. -
  185. -   if (surf->format->BitsPerPixel != 8 || surf->format->BytesPerPixel != 1) {
  186. -       fprintf(stderr, "Rendering text failed (Wrong surface format)\n");
  187. -       return;
  188. -   }
  189. +   this->blit_rect.ValidateAddress();
  190.  
  191. -   int real_w = std::min(surf->w, width);
  192. +   int w, h;
  193. +   this->GetTextSize(text, &w, &h);
  194. +   ypos += h;
  195. +   int real_w = std::min(w, width);
  196.     switch (align) {
  197.         case ALG_LEFT:
  198.             break;
  199. @@ -804,45 +857,42 @@ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos,
  200.         default: NOT_REACHED();
  201.     }
  202.  
  203. -   this->blit_rect.ValidateAddress();
  204. +   bool use_kerning = FT_HAS_KERNING(this->face);
  205. +   uint previous = 0;
  206. +   FT_GlyphSlot slot = this->face->glyph;
  207.  
  208. -   uint8 *src = ((uint8 *)surf->pixels);
  209. -   uint32 *dest = this->blit_rect.address + xpos + ypos * this->blit_rect.pitch;
  210. -   int h = surf->h;
  211. -   if (ypos < 0) {
  212. -       h += ypos;
  213. -       src  -= ypos * surf->pitch;
  214. -       dest -= ypos * this->blit_rect.pitch;
  215. -       ypos = 0;
  216. -   }
  217. -   while (h > 0) {
  218. -       if (ypos >= this->blit_rect.height) break;
  219. -       uint8 *src2 = src;
  220. -       uint32 *dest2 = dest;
  221. -       int w = real_w;
  222. -       int x = xpos;
  223. -       if (x < 0) {
  224. -           w += x;
  225. -           if (w <= 0) break;
  226. -           dest2 -= x;
  227. -           src2 -= x;
  228. -           x = 0;
  229. +   for (const uint8 *pt = text; *pt != '\0';) {
  230. +       uint32 u32;
  231. +       int len = DecodeUtf8Char(pt, strlen((const char *)pt), &u32);
  232. +       if (len == 0) break;
  233. +       pt += len;
  234. +
  235. +       uint glyph = FT_Get_Char_Index(this->face, u32);
  236. +
  237. +       if (use_kerning && previous && glyph) {
  238. +           FT_Vector delta;
  239. +           FT_Get_Kerning(this->face, previous, glyph, FT_KERNING_DEFAULT, &delta);
  240. +           xpos += delta.x >> 6;
  241.         }
  242. -       while (w > 0) {
  243. -           if (x >= this->blit_rect.width) break;
  244. -           if (*src2 != 0) *dest2 = colour;
  245. -           src2++;
  246. -           dest2++;
  247. -           x++;
  248. -           w--;
  249. +
  250. +       if (FT_Load_Glyph(this->face, glyph, FT_LOAD_RENDER) != 0) {
  251.         }
  252. -       ypos++;
  253. -       src  += surf->pitch;
  254. -       dest += this->blit_rect.pitch;
  255. -       h--;
  256. -   }
  257.  
  258. -   SDL_FreeSurface(surf);
  259. +       uint32 *dest = this->blit_rect.address + (xpos + slot->bitmap_left) + (ypos - slot->bitmap_top) * this->blit_rect.pitch;
  260. +       for (int i = 0; i < slot->bitmap.rows; i++) {
  261. +           if (ypos - slot->bitmap_top + i < 0) continue;
  262. +           for (int j = 0; j < slot->bitmap.pitch; j++) {
  263. +               if (xpos + slot->bitmap_left + j < 0) continue;
  264. +               if (slot->bitmap.buffer[i * slot->bitmap.pitch + j] != 0) {
  265. +                   dest[i * this->blit_rect.pitch + j] = colour;
  266. +               }
  267. +           }
  268. +       }
  269. +
  270. +       previous = glyph;
  271. +       xpos += slot->advance.x >> 6;
  272. +       ypos += slot->advance.y >> 6;
  273. +   }
  274.  }
  275.  
  276.  /**
  277. diff --git a/src/video.h b/src/video.h
  278. index 4528f81..e273b79 100644
  279. --- a/src/video.h
  280. +++ b/src/video.h
  281. @@ -13,8 +13,11 @@
  282.  #define VIDEO_H
  283.  
  284.  #include <set>
  285. +
  286.  #include <SDL.h>
  287. -#include <SDL_ttf.h>
  288. +#include <ft2build.h>
  289. +#include FT_FREETYPE_H
  290. +
  291.  #include "geometry.h"
  292.  #include "palette.h"
  293.  
  294. @@ -169,7 +172,9 @@ private:
  295.     bool initialized; ///< Video system is initialized.
  296.     bool dirty;       ///< Video display needs being repainted.
  297.  
  298. -   TTF_Font *font;             ///< Opened text font.
  299. +   FT_Library library;
  300. +   FT_Face face;
  301. +
  302.     SDL_Window *window;         ///< %Window of the application.
  303.     SDL_Renderer *renderer;     ///< GPU renderer to the application window.
  304.     SDL_Texture *texture;       ///< GPU Texture storage of the application window.
  305.  

Comments