SDL TTF - 换行和更改换行高度?
SDL TTF - Line wrapping & changing height of wrapped lines?
我最近一直在使用 SDL2 编写一个小型文本冒险游戏,但遇到了换行问题。我正在使用 TTF_RenderText_Blended_Wrapped() 来呈现我的字符串,这给了我一些很好的包裹线。但是行高是个问题,行似乎被压在一起,像 'jqg' 这样的字母与像 'tli' 这样的字母重叠。
有谁知道有没有办法改变行高? TTF_RenderText_Blended_Wrapped() 甚至还没有出现在 SDL_ttf 的文档中。我应该只编写自己的文本换行函数吗?
字体大小为16pt,样式为TTF_STYLE_BOLD,字体可以找到here. The code below should reproduce the error, there is almost no error checking though, use at your own risk. Here is the output of the code:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
int main(int argc, char *argv[]) {
SDL_Window *gui;
SDL_Surface *screen, *text;
SDL_Event ev;
TTF_Font *font;
int running = 1;
const char *SAMPLETEXT = "This is an example of my problem, for most lines it works fine, albeit it looks a bit tight. But for any letters that \"hang\" below the line, there is a chance of overlapping with the letters below. This isn\'t the end of the world, but I think it makes for rather cluttered text.\n\nNotice the p and k on line 1/2, and the g/t on 2/3 and 3/4.";
// init SDL/TTF
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
// Open and set up font
font = TTF_OpenFont("Anonymous.ttf", 16);
if(font == NULL) {
fprintf(stderr, "Error: font could not be opened.\n");
return 0;
}
TTF_SetFontStyle(font, TTF_STYLE_BOLD);
// Create GUI
gui = SDL_CreateWindow("Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480, SDL_WINDOW_SHOWN);
// Grab GUI surface
screen = SDL_GetWindowSurface(gui);
// Clear screen black
SDL_FillRect(screen, NULL, 0);
// Draw some text to screen
SDL_Color color = {0xff, 0xff, 0xff, 0xff};
text = TTF_RenderText_Blended_Wrapped(font, SAMPLETEXT, color, screen->w);
SDL_BlitSurface(text, NULL, screen, NULL);
while(running) { // Main loop
while(SDL_PollEvent(&ev)) {
switch(ev.type){
case SDL_QUIT:
running = 0;
break;
}
}
SDL_UpdateWindowSurface(gui); // Refresh window
SDL_Delay(20); // Delay loop
}
// Destroy resources and quit
TTF_CloseFont(font);
TTF_Quit();
SDL_FreeSurface(text);
SDL_DestroyWindow(gui);
SDL_Quit();
return 0;
}
最简单的解决方案是找到没有该问题的字体。 FreeMono font 的间距更大:
从 TTF_RenderText_Blended_Wrapped
调用的 source code for TTF_RenderUTF8_Blended_Wrapped
来看,没有可配置的方法来设置行间距。请参阅第 1893 行 const int lineSpace = 2;
。
但是,即使 lineSpace
设置为 2,在计算要渲染的每个像素的地址时也不会使用它。这实际上是将行间距设置为 0。我将此报告为 SDL_ttf 库中的错误:https://bugzilla.libsdl.org/show_bug.cgi?id=3679
我能够通过以下更改解决 SDL_ttf 2.0.14 中的问题:
--- a/SDL_ttf.c Fri Jan 27 17:54:34 2017 -0800
+++ b/SDL_ttf.c Thu Jun 22 16:54:38 2017 -0700
@@ -1996,7 +1996,7 @@
return(NULL);
}
- rowSize = textbuf->pitch/4 * height;
+ rowSize = textbuf->pitch/4 * (height + lineSpace);
/* Adding bound checking to avoid all kinds of memory corruption errors
that may occur. */
应用上述补丁后,您的示例程序显示正确的行距 Anonymous font:
我最近一直在使用 SDL2 编写一个小型文本冒险游戏,但遇到了换行问题。我正在使用 TTF_RenderText_Blended_Wrapped() 来呈现我的字符串,这给了我一些很好的包裹线。但是行高是个问题,行似乎被压在一起,像 'jqg' 这样的字母与像 'tli' 这样的字母重叠。
有谁知道有没有办法改变行高? TTF_RenderText_Blended_Wrapped() 甚至还没有出现在 SDL_ttf 的文档中。我应该只编写自己的文本换行函数吗?
字体大小为16pt,样式为TTF_STYLE_BOLD,字体可以找到here. The code below should reproduce the error, there is almost no error checking though, use at your own risk. Here is the output of the code:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
int main(int argc, char *argv[]) {
SDL_Window *gui;
SDL_Surface *screen, *text;
SDL_Event ev;
TTF_Font *font;
int running = 1;
const char *SAMPLETEXT = "This is an example of my problem, for most lines it works fine, albeit it looks a bit tight. But for any letters that \"hang\" below the line, there is a chance of overlapping with the letters below. This isn\'t the end of the world, but I think it makes for rather cluttered text.\n\nNotice the p and k on line 1/2, and the g/t on 2/3 and 3/4.";
// init SDL/TTF
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
// Open and set up font
font = TTF_OpenFont("Anonymous.ttf", 16);
if(font == NULL) {
fprintf(stderr, "Error: font could not be opened.\n");
return 0;
}
TTF_SetFontStyle(font, TTF_STYLE_BOLD);
// Create GUI
gui = SDL_CreateWindow("Example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480, SDL_WINDOW_SHOWN);
// Grab GUI surface
screen = SDL_GetWindowSurface(gui);
// Clear screen black
SDL_FillRect(screen, NULL, 0);
// Draw some text to screen
SDL_Color color = {0xff, 0xff, 0xff, 0xff};
text = TTF_RenderText_Blended_Wrapped(font, SAMPLETEXT, color, screen->w);
SDL_BlitSurface(text, NULL, screen, NULL);
while(running) { // Main loop
while(SDL_PollEvent(&ev)) {
switch(ev.type){
case SDL_QUIT:
running = 0;
break;
}
}
SDL_UpdateWindowSurface(gui); // Refresh window
SDL_Delay(20); // Delay loop
}
// Destroy resources and quit
TTF_CloseFont(font);
TTF_Quit();
SDL_FreeSurface(text);
SDL_DestroyWindow(gui);
SDL_Quit();
return 0;
}
最简单的解决方案是找到没有该问题的字体。 FreeMono font 的间距更大:
从 TTF_RenderText_Blended_Wrapped
调用的 source code for TTF_RenderUTF8_Blended_Wrapped
来看,没有可配置的方法来设置行间距。请参阅第 1893 行 const int lineSpace = 2;
。
但是,即使 lineSpace
设置为 2,在计算要渲染的每个像素的地址时也不会使用它。这实际上是将行间距设置为 0。我将此报告为 SDL_ttf 库中的错误:https://bugzilla.libsdl.org/show_bug.cgi?id=3679
我能够通过以下更改解决 SDL_ttf 2.0.14 中的问题:
--- a/SDL_ttf.c Fri Jan 27 17:54:34 2017 -0800
+++ b/SDL_ttf.c Thu Jun 22 16:54:38 2017 -0700
@@ -1996,7 +1996,7 @@
return(NULL);
}
- rowSize = textbuf->pitch/4 * height;
+ rowSize = textbuf->pitch/4 * (height + lineSpace);
/* Adding bound checking to avoid all kinds of memory corruption errors
that may occur. */
应用上述补丁后,您的示例程序显示正确的行距 Anonymous font: