【问题标题】:SDL TTF - Line wrapping & changing height of wrapped lines?SDL TTF - 换行和改变换行高度?
【发布时间】:2017-06-22 14:10:17
【问题描述】:

我最近一直在使用 SDL2 编写一个小型文本冒险游戏,但遇到了换行问题。我正在使用 TTF_RenderText_Blended_Wrapped() 来渲染我的字符串,这给了我一些很好的包裹线。但是行高是个问题,行似乎挤在一起,像“jqg”这样的字母与像“tli”这样的字母重叠。

有谁知道是否有办法改变行高? TTF_RenderText_Blended_Wrapped() 甚至还没有出现在 SDL_ttf 的文档中。我应该只编写自己的文本换行函数吗?

字体大小为16pt,样式为TTF_STYLE_BOLD,字体可以在here找到。下面的代码应该重现错误,但几乎没有错误检查,使用风险自负。这是代码的输出:

#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;
}

【问题讨论】:

  • 我看不出有什么方法可以控制行距。 Here is a link to the source code。你试过不同的字体吗?你比较过TTF_FontHeight()TTF_FontLineSkip()返回的值吗?
  • 感谢您的链接。跳线大于高度,我尝试了几种字体。我确信某处有一种字体可以使用,但我宁愿不去搜索。
  • 你能发布你正在使用的字体吗?我在我的系统上尝试了几种字体,但无法重现该问题。
  • This is the font,我尝试了其他几个,但如果您没有问题,我可能应该再测试几个。
  • 您可以发布错误渲染文本的图像吗?另外,您使用的是什么字体大小和样式?

标签: c sdl-2 sdl-ttf


【解决方案1】:

最简单的解决方案是找到没有该问题的字体。 FreeMono font 的间距更大:

source code for TTF_RenderUTF8_Blended_Wrapped(由TTF_RenderText_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

【讨论】:

    猜你喜欢
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    相关资源
    最近更新 更多