From 497e8c6c49996c37922cae01c031e8facd24ed9b Mon Sep 17 00:00:00 2001 From: ZHK Date: Sun, 4 Feb 2024 11:24:00 +0800 Subject: [PATCH] Modifications: - Added argument [-windowsize w,h] to specify the windows size. - added argument [-utf8txtfile pathName] to support message from utf8 file. - removed [-utf8|-unicode], since the utf8 or unicode text cannot be input from console. - fixed [-wrapped] display. --- examples/showfont.c | 361 +++++++++++++++++++++++++------------------- 1 file changed, 207 insertions(+), 154 deletions(-) diff --git a/examples/showfont.c b/examples/showfont.c index 7b12f4b4..f88c02f1 100644 --- a/examples/showfont.c +++ b/examples/showfont.c @@ -25,17 +25,18 @@ #include #include -#include +#include #include +#include #include -#define DEFAULT_PTSIZE 18 -#define DEFAULT_TEXT "The quick brown fox jumped over the lazy dog" -#define WIDTH 640 -#define HEIGHT 480 +#define DEFAULT_PTSIZE 18 +#define DEFAULT_TEXT "The quick brown fox jumped over the lazy dog" +#define WIDTH 1280 +#define HEIGHT 800 #define TTF_SHOWFONT_USAGE \ -"Usage: %s [-solid] [-shaded] [-blended] [-wrapped] [-utf8|-unicode] [-b] [-i] [-u] [-s] [-outline size] [-hintlight|-hintmono|-hintnone] [-nokerning] [-wrap] [-fgcol r,g,b,a] [-bgcol r,g,b,a] .ttf [ptsize] [text]\n" + "Usage: %s [-windowsize w,h] [-solid] [-shaded] [-blended] [-wrapped] [-b] [-i] [-u] [-s] [-outline size] [-hintlight|-hintmono|-hintnone] [-nokerning] [-wrap] [-fgcol r,g,b,a] [-bgcol r,g,b,a] [-utf8txtfile pathName] .ttf [ptsize] [text]\n" typedef enum { @@ -44,7 +45,8 @@ typedef enum TextRenderBlended } TextRenderMethod; -typedef struct { +typedef struct +{ SDL_Texture *caption; SDL_FRect captionRect; SDL_Texture *message; @@ -69,6 +71,50 @@ static void cleanup(int exitcode) exit(exitcode); } +int load_file(char **bufferAddr, const char *pathName) +{ + FILE *file = fopen(pathName, "rb"); + if (file == NULL) { + perror("Error opening file"); + return 1; + } + + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + + if (file_size == 0) { + fclose(file); + return 0; + } + + fseek(file, 0, SEEK_SET); + + *bufferAddr = malloc(file_size + 1); + char *buffer = *bufferAddr; + memset(buffer, 0, file_size + 1); + + size_t bytesRead = fread(buffer, 1, file_size, file); + if (bytesRead == 0) { + perror("Error reading file"); + fclose(file); + return 1; + } + + if (fread(buffer, file_size, 1, file) != 0) { + return 1; + } + + for (int i = 0; i < file_size; ++i) { + if (iscntrl(buffer[i])) { + buffer[i] = 32; + } + } + + fclose(file); + + return 0; +} + int main(int argc, char *argv[]) { char *argv0 = argv[0]; @@ -91,12 +137,17 @@ int main(int argc, char *argv[]) int kerning; int wrap; int dump; - enum { + int winWidth = WIDTH; + int winHeight = HEIGHT; + int wrapWidth = WIDTH - 10; + enum + { RENDER_LATIN1, RENDER_UTF8, RENDER_UNICODE } rendertype; - char *message, string[128]; + char *message, *fileMessage, string[128]; + fileMessage = NULL; /* Look for special execution mode */ dump = 0; @@ -110,82 +161,77 @@ int main(int argc, char *argv[]) /* Default is black and white */ forecol = &black; backcol = &white; - for (i=1; argv[i] && argv[i][0] == '-'; ++i) { + + if (argc == 1) { + SDL_Log(TTF_SHOWFONT_USAGE, argv0); + return (1); + } + + for (i = 1; argv[i] && argv[i][0] == '-'; ++i) { if (SDL_strcmp(argv[i], "-solid") == 0) { rendermethod = TextRenderSolid; - } else - if (SDL_strcmp(argv[i], "-shaded") == 0) { + } else if (SDL_strcmp(argv[i], "-shaded") == 0) { rendermethod = TextRenderShaded; - } else - if (SDL_strcmp(argv[i], "-blended") == 0) { + } else if (SDL_strcmp(argv[i], "-blended") == 0) { rendermethod = TextRenderBlended; - } else - if (SDL_strcmp(argv[i], "-utf8") == 0) { - rendertype = RENDER_UTF8; - } else - if (SDL_strcmp(argv[i], "-unicode") == 0) { - rendertype = RENDER_UNICODE; - } else - if (SDL_strcmp(argv[i], "-b") == 0) { + } else if (SDL_strcmp(argv[i], "-b") == 0) { renderstyle |= TTF_STYLE_BOLD; - } else - if (SDL_strcmp(argv[i], "-i") == 0) { + } else if (SDL_strcmp(argv[i], "-i") == 0) { renderstyle |= TTF_STYLE_ITALIC; - } else - if (SDL_strcmp(argv[i], "-u") == 0) { + } else if (SDL_strcmp(argv[i], "-u") == 0) { renderstyle |= TTF_STYLE_UNDERLINE; - } else - if (SDL_strcmp(argv[i], "-s") == 0) { + } else if (SDL_strcmp(argv[i], "-s") == 0) { renderstyle |= TTF_STYLE_STRIKETHROUGH; - } else - if (SDL_strcmp(argv[i], "-outline") == 0) { + } else if (SDL_strcmp(argv[i], "-outline") == 0) { if (SDL_sscanf(argv[++i], "%d", &outline) != 1) { SDL_Log(TTF_SHOWFONT_USAGE, argv0); - return(1); + return (1); } - } else - if (SDL_strcmp(argv[i], "-hintlight") == 0) { + } else if (SDL_strcmp(argv[i], "-hintlight") == 0) { hinting = TTF_HINTING_LIGHT; - } else - if (SDL_strcmp(argv[i], "-hintmono") == 0) { + } else if (SDL_strcmp(argv[i], "-hintmono") == 0) { hinting = TTF_HINTING_MONO; - } else - if (SDL_strcmp(argv[i], "-hintnone") == 0) { + } else if (SDL_strcmp(argv[i], "-hintnone") == 0) { hinting = TTF_HINTING_NONE; - } else - if (SDL_strcmp(argv[i], "-nokerning") == 0) { + } else if (SDL_strcmp(argv[i], "-nokerning") == 0) { kerning = 0; - } else - if (SDL_strcmp(argv[i], "-wrap") == 0) { + } else if (SDL_strcmp(argv[i], "-wrap") == 0) { wrap = 1; - } else - if (SDL_strcmp(argv[i], "-dump") == 0) { + } else if (SDL_strcmp(argv[i], "-dump") == 0) { dump = 1; - } else - if (SDL_strcmp(argv[i], "-fgcol") == 0) { + } else if (SDL_strcmp(argv[i], "-fgcol") == 0) { int r, g, b, a = 0xFF; if (SDL_sscanf(argv[++i], "%d,%d,%d,%d", &r, &g, &b, &a) < 3) { SDL_Log(TTF_SHOWFONT_USAGE, argv0); - return(1); + return (1); } forecol->r = (Uint8)r; forecol->g = (Uint8)g; forecol->b = (Uint8)b; forecol->a = (Uint8)a; - } else - if (SDL_strcmp(argv[i], "-bgcol") == 0) { + } else if (SDL_strcmp(argv[i], "-bgcol") == 0) { int r, g, b, a = 0xFF; if (SDL_sscanf(argv[++i], "%d,%d,%d,%d", &r, &g, &b, &a) < 3) { SDL_Log(TTF_SHOWFONT_USAGE, argv0); - return(1); + return (1); } backcol->r = (Uint8)r; backcol->g = (Uint8)g; backcol->b = (Uint8)b; backcol->a = (Uint8)a; + } else if (SDL_strcmp(argv[i], "-utf8txtfile") == 0) { + load_file(&fileMessage, argv[++i]); + rendertype = RENDER_UTF8; + wrap = 1; + } else if (SDL_strcmp(argv[i], "-windowsize") == 0) { + if (SDL_sscanf(argv[++i], "%d,%d", &winWidth, &winHeight) < 2) { + SDL_Log(TTF_SHOWFONT_USAGE, argv0); + return (1); + } + wrapWidth = winWidth - 10; } else { SDL_Log(TTF_SHOWFONT_USAGE, argv0); - return(1); + return (1); } } argv += i; @@ -194,14 +240,14 @@ int main(int argc, char *argv[]) /* Check usage */ if (!argv[0]) { SDL_Log(TTF_SHOWFONT_USAGE, argv0); - return(1); + return (1); } /* Initialize the TTF library */ if (TTF_Init() < 0) { - SDL_Log("Couldn't initialize TTF: %s\n",SDL_GetError()); + SDL_Log("Couldn't initialize TTF: %s\n", SDL_GetError()); SDL_Quit(); - return(2); + return (2); } /* Open the font file with the requested point size */ @@ -218,7 +264,7 @@ int main(int argc, char *argv[]) font = TTF_OpenFont(argv[0], ptsize); if (font == NULL) { SDL_Log("Couldn't load %d pt font from %s: %s\n", - ptsize, argv[0], SDL_GetError()); + ptsize, argv[0], SDL_GetError()); cleanup(2); } TTF_SetFontStyle(font, renderstyle); @@ -226,30 +272,29 @@ int main(int argc, char *argv[]) TTF_SetFontKerning(font, kerning); TTF_SetFontHinting(font, hinting); - if(dump) { - for(i = 48; i < 123; i++) { - SDL_Surface* glyph = NULL; + if (dump) { + for (i = 48; i < 123; i++) { + SDL_Surface *glyph = NULL; glyph = TTF_RenderGlyph_Shaded(font, i, *forecol, *backcol); - if(glyph) { + if (glyph) { char outname[64]; SDL_snprintf(outname, sizeof(outname), "glyph-%d.bmp", i); SDL_SaveBMP(glyph, outname); } - } cleanup(0); } /* Create a window */ - if (SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, 0, &window, &renderer) < 0) { + if (SDL_CreateWindowAndRenderer(winWidth, winHeight, 0, &window, &renderer) < 0) { SDL_Log("SDL_CreateWindowAndRenderer() failed: %s\n", SDL_GetError()); cleanup(2); } /* Show which font file we're looking at */ - SDL_snprintf(string, sizeof(string), "Font file: %s", argv[0]); /* possible overflow */ + SDL_snprintf(string, sizeof(string), "Font file: %s", argv[0]); /* possible overflow */ switch (rendermethod) { case TextRenderSolid: text = TTF_RenderText_Solid(font, string, *forecol); @@ -271,106 +316,110 @@ int main(int argc, char *argv[]) } /* Render and center the message */ - if (argc > 2) { - message = argv[2]; + if (fileMessage != NULL) { + message = fileMessage; } else { - message = DEFAULT_TEXT; + if (argc > 2) { + message = argv[2]; + } else { + message = DEFAULT_TEXT; + } } + switch (rendertype) { - case RENDER_LATIN1: - switch (rendermethod) { - case TextRenderSolid: - if (wrap) { - text = TTF_RenderText_Solid_Wrapped(font, message, *forecol, 0); - } else { - text = TTF_RenderText_Solid(font, message, *forecol); - } - break; - case TextRenderShaded: - if (wrap) { - text = TTF_RenderText_Shaded_Wrapped(font, message, *forecol, *backcol, 0); - } else { - text = TTF_RenderText_Shaded(font, message, *forecol, *backcol); - } - break; - case TextRenderBlended: - if (wrap) { - text = TTF_RenderText_Blended_Wrapped(font, message, *forecol, 0); - } else { - text = TTF_RenderText_Blended(font, message, *forecol); - } - break; + case RENDER_LATIN1: + switch (rendermethod) { + case TextRenderSolid: + if (wrap) { + text = TTF_RenderText_Solid_Wrapped(font, message, *forecol, wrapWidth); + } else { + text = TTF_RenderText_Solid(font, message, *forecol); } break; - - case RENDER_UTF8: - switch (rendermethod) { - case TextRenderSolid: - if (wrap) { - text = TTF_RenderUTF8_Solid_Wrapped(font, message, *forecol, 0); - } else { - text = TTF_RenderUTF8_Solid(font, message, *forecol); - } - break; - case TextRenderShaded: - if (wrap) { - text = TTF_RenderUTF8_Shaded_Wrapped(font, message, *forecol, *backcol, 0); - } else { - text = TTF_RenderUTF8_Shaded(font, message, *forecol, *backcol); - } - break; - case TextRenderBlended: - if (wrap) { - text = TTF_RenderUTF8_Blended_Wrapped(font, message, *forecol, 0); - } else { - text = TTF_RenderUTF8_Blended(font, message, *forecol); - } - break; + case TextRenderShaded: + if (wrap) { + text = TTF_RenderText_Shaded_Wrapped(font, message, *forecol, *backcol, wrapWidth); + } else { + text = TTF_RenderText_Shaded(font, message, *forecol, *backcol); + } + break; + case TextRenderBlended: + if (wrap) { + text = TTF_RenderText_Blended_Wrapped(font, message, *forecol, wrapWidth); + } else { + text = TTF_RenderText_Blended(font, message, *forecol); } break; + } + break; - case RENDER_UNICODE: - { - Uint16 *unicode_text = SDL_iconv_utf8_ucs2(message); - switch (rendermethod) { - case TextRenderSolid: - if (wrap) { - text = TTF_RenderUNICODE_Solid_Wrapped(font, unicode_text, *forecol, 0); - } else { - text = TTF_RenderUNICODE_Solid(font, unicode_text, *forecol); - } - break; - case TextRenderShaded: - if (wrap) { - text = TTF_RenderUNICODE_Shaded_Wrapped(font, unicode_text, *forecol, *backcol, 0); - } else { - text = TTF_RenderUNICODE_Shaded(font, unicode_text, *forecol, *backcol); - } - break; - case TextRenderBlended: - if (wrap) { - text = TTF_RenderUNICODE_Blended_Wrapped(font, unicode_text, *forecol, 0); - } else { - text = TTF_RenderUNICODE_Blended(font, unicode_text, *forecol); - } - break; + case RENDER_UTF8: + switch (rendermethod) { + case TextRenderSolid: + if (wrap) { + text = TTF_RenderUTF8_Solid_Wrapped(font, message, *forecol, wrapWidth); + } else { + text = TTF_RenderUTF8_Solid(font, message, *forecol); + } + break; + case TextRenderShaded: + if (wrap) { + text = TTF_RenderUTF8_Shaded_Wrapped(font, message, *forecol, *backcol, wrapWidth); + } else { + text = TTF_RenderUTF8_Shaded(font, message, *forecol, *backcol); } - SDL_free(unicode_text); + break; + case TextRenderBlended: + if (wrap) { + text = TTF_RenderUTF8_Blended_Wrapped(font, message, *forecol, wrapWidth); + } else { + text = TTF_RenderUTF8_Blended(font, message, *forecol); + } + break; } break; + + case RENDER_UNICODE: + { + Uint16 *unicode_text = SDL_iconv_utf8_ucs2(message); + switch (rendermethod) { + case TextRenderSolid: + if (wrap) { + text = TTF_RenderUNICODE_Solid_Wrapped(font, unicode_text, *forecol, wrapWidth); + } else { + text = TTF_RenderUNICODE_Solid(font, unicode_text, *forecol); + } + break; + case TextRenderShaded: + if (wrap) { + text = TTF_RenderUNICODE_Shaded_Wrapped(font, unicode_text, *forecol, *backcol, wrapWidth); + } else { + text = TTF_RenderUNICODE_Shaded(font, unicode_text, *forecol, *backcol); + } + break; + case TextRenderBlended: + if (wrap) { + text = TTF_RenderUNICODE_Blended_Wrapped(font, unicode_text, *forecol, wrapWidth); + } else { + text = TTF_RenderUNICODE_Blended(font, unicode_text, *forecol); + } + break; + } + SDL_free(unicode_text); + } break; } if (text == NULL) { SDL_Log("Couldn't render text: %s\n", SDL_GetError()); TTF_CloseFont(font); cleanup(2); } - scene.messageRect.x = (float)((WIDTH - text->w)/2); - scene.messageRect.y = (float)((HEIGHT - text->h)/2); + scene.messageRect.x = (float)((winWidth - text->w) / 2); + scene.messageRect.y = (float)((winHeight - text->h) / 2); scene.messageRect.w = (float)text->w; scene.messageRect.h = (float)text->h; scene.message = SDL_CreateTextureFromSurface(renderer, text); SDL_Log("Font is generally %d big, and string is %d big\n", - TTF_FontHeight(font), text->h); + TTF_FontHeight(font), text->h); draw_scene(renderer, &scene); @@ -383,20 +432,20 @@ int main(int argc, char *argv[]) continue; } switch (event.type) { - case SDL_EVENT_MOUSE_BUTTON_DOWN: - scene.messageRect.x = (float)(event.button.x - text->w/2); - scene.messageRect.y = (float)(event.button.y - text->h/2); - scene.messageRect.w = (float)text->w; - scene.messageRect.h = (float)text->h; - draw_scene(renderer, &scene); - break; - - case SDL_EVENT_KEY_DOWN: - case SDL_EVENT_QUIT: - done = 1; - break; - default: - break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + scene.messageRect.x = (float)(event.button.x - text->w / 2); + scene.messageRect.y = (float)(event.button.y - text->h / 2); + scene.messageRect.w = (float)text->w; + scene.messageRect.h = (float)text->h; + draw_scene(renderer, &scene); + break; + + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_QUIT: + done = 1; + break; + default: + break; } } SDL_DestroySurface(text); @@ -405,6 +454,10 @@ int main(int argc, char *argv[]) SDL_DestroyTexture(scene.message); cleanup(0); + if (fileMessage != NULL) { + free(fileMessage); + } + /* Not reached, but fixes compiler warnings */ return 0; }