From 8ce76892ef279e35c3c81b81ed584bfad9a6ef1d Mon Sep 17 00:00:00 2001 From: zeromake Date: Sun, 21 Apr 2024 21:04:52 +0800 Subject: [PATCH] feat: support script config font --- src/FontConfig.cpp | 67 ++++++++++++++++++++++++++++++ src/FontConfig.h | 57 ++++++++++++------------- src/ScriptHandler.cpp | 29 +++++++++++++ src/ScriptHandler.h | 3 ++ src/ScriptParser.cpp | 61 ++++----------------------- src/ScriptParser.h | 2 +- src/onscripter/ONScripter_text.cpp | 6 ++- 7 files changed, 143 insertions(+), 82 deletions(-) diff --git a/src/FontConfig.cpp b/src/FontConfig.cpp index 328f6cb..3781714 100644 --- a/src/FontConfig.cpp +++ b/src/FontConfig.cpp @@ -1,7 +1,74 @@ #include "FontConfig.h" +#include +#include namespace ons_font { const static FontConfig __DEFAULT_FONT_CONFIG = FontConfig{0, 0, {0xff, 0xff, 0xff}, false, 1, {0x0, 0x0, 0x0}, 0, 0}; const FontConfig* DEFAULT_FONT_CONFIG() { return &__DEFAULT_FONT_CONFIG; } + +const int readFontConfig(const char *buf, ons_font::FontConfig *cfg) { + ons_font::FONT_TYPE types = ons_font::GLOBAL_FONT; + int offset = 0; + if (buf[offset] >= '0' && buf[offset] <= '9') { + types = ons_font::FONT_TYPE(buf[offset] - '0'); + } + offset++; + if (buf[offset] != ':') { + return 0; + } + offset++; + auto default_config = ons_font::DEFAULT_FONT_CONFIG(); + memcpy(cfg, default_config, sizeof(ons_font::FontConfig)); + int start = offset; + int field = 0; + char buff[256]; + #define IS_FONT_CONFIG_END(c) (c == '\0' || c == ';' || c == ' ' || c == '\n') + while (1) { + if (buf[offset] == ',' || IS_FONT_CONFIG_END(buf[offset])) { + int size = offset - start; + if (size > 0) { + memcpy(buff, buf + start, size); + buff[size] = '\0'; + } else { + buff[0] = '\0'; + } + start = offset + 1; + if (buff[0] != '\0') { + switch (field) { + case 0: + cfg->size = atoi(buff); + break; + case 1: + cfg->size_ratio = atof(buff); + break; + case 2: + utils::readColor(buff, &cfg->color); + break; + case 3: + cfg->render_outline = buff[0] != '0' && buff[0] != 'f'; + break; + case 4: + cfg->outline_size = atoi(buff); + break; + case 5: + readColor(buff, &cfg->outline_color); + break; + case 6: + cfg->offset_x = atoi(buff); + break; + case 7: + cfg->offset_y = atoi(buff); + break; + } + } + field++; + } + if (IS_FONT_CONFIG_END(buf[offset])) { + break; + } + offset++; + } + return offset; +} }; // namespace ons_font diff --git a/src/FontConfig.h b/src/FontConfig.h index 02353ce..e0dce9b 100644 --- a/src/FontConfig.h +++ b/src/FontConfig.h @@ -1,28 +1,29 @@ - -#ifndef __FONT_CONFIG_H__ -#define __FONT_CONFIG_H__ - -namespace ons_font { -typedef unsigned char uchar3[3]; -enum FONT_TYPE { - GLOBAL_FONT, - SENTENCE_FONT, - ANIM_FONT, - MENU_FONT, - DAILOG_FONT, - RUBY_FONT, -}; -struct FontConfig { - int size; - float size_ratio; - uchar3 color; - bool render_outline; - int outline_size; - uchar3 outline_color; - int offset_x; - int offset_y; -}; -const FontConfig* DEFAULT_FONT_CONFIG(); -} // namespace ons_font - -#endif \ No newline at end of file + +#ifndef __FONT_CONFIG_H__ +#define __FONT_CONFIG_H__ +#include "private/utils.h" + +namespace ons_font { +enum FONT_TYPE { + GLOBAL_FONT, + SENTENCE_FONT, + ANIM_FONT, + MENU_FONT, + DAILOG_FONT, + RUBY_FONT, +}; +struct FontConfig { + int size; + float size_ratio; + utils::uchar4 color; + bool render_outline; + int outline_size; + utils::uchar4 outline_color; + int offset_x; + int offset_y; +}; +const FontConfig* DEFAULT_FONT_CONFIG(); +const int readFontConfig(const char *buf, ons_font::FontConfig *cfg); +} // namespace ons_font + +#endif diff --git a/src/ScriptHandler.cpp b/src/ScriptHandler.cpp index dd5aaae..33bf513 100644 --- a/src/ScriptHandler.cpp +++ b/src/ScriptHandler.cpp @@ -73,6 +73,12 @@ ScriptHandler::~ScriptHandler() { delete[] str_string_buffer; delete[] saved_string_buffer; if (variable_data) delete[] variable_data; + for (int i = 0; i < 6; i++) { + if (font_configs[i] != nullptr) { + delete font_configs[i]; + font_configs[i] = nullptr; + } + } } void ScriptHandler::reset() { @@ -1269,6 +1275,26 @@ int ScriptHandler::readScriptSub(FILE *fp, char **buf, int encrypt_mode) { return 0; } +int ScriptHandler::setFontConfig(const char *buf) { + // printf("setFontConfig: %s\n", buf); + ons_font::FONT_TYPE types = ons_font::GLOBAL_FONT; + int offset = 0; + if (buf[offset] >= '0' && buf[offset] <= '9') { + types = ons_font::FONT_TYPE(buf[offset] - '0'); + } + offset++; + if (buf[offset] != ':') { + return 0; + } + offset++; + ons_font::FontConfig *cfg = nullptr; + if (font_configs[types] == nullptr) { + font_configs[types] = new ons_font::FontConfig; + } + cfg = font_configs[types]; + return ons_font::readFontConfig(buf, cfg); +} + void ScriptHandler::readConfiguration() { variable_range = 4096; global_variable_border = 200; @@ -1371,6 +1397,9 @@ void ScriptHandler::readConfiguration() { buf++; SKIP_SPACE(buf); while (*buf >= '0' && *buf <= '9') buf++; + } else if (*buf == 'f' || *buf == 'F') { + buf++; + buf += setFontConfig(buf); } else if (!strncmp(buf, "ratio", 5)) { int _user_ratio = 0; buf += 5; diff --git a/src/ScriptHandler.h b/src/ScriptHandler.h index bc7e5f0..f4c090b 100644 --- a/src/ScriptHandler.h +++ b/src/ScriptHandler.h @@ -31,6 +31,7 @@ #include +#include "FontConfig.h" #include "BaseReader.h" #include "private/utils.h" #include "resize/scale_manager.hpp" @@ -264,6 +265,7 @@ class ScriptHandler { struct VariableData current_variable_data; onscripter::SharedPtr screen_scale; onscripter::SharedPtr user_scale; + ons_font::FontConfig *font_configs[6] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; private: enum { @@ -322,6 +324,7 @@ class ScriptHandler { int readScriptSub(FILE *fp, char **buf, int encrypt_mode); void readConfiguration(); int labelScript(); + int setFontConfig(const char *buf); int findLabel(const char *label); diff --git a/src/ScriptParser.cpp b/src/ScriptParser.cpp index d1a0b0c..5d2b273 100644 --- a/src/ScriptParser.cpp +++ b/src/ScriptParser.cpp @@ -122,7 +122,7 @@ const ons_font::FontConfig *ScriptParser::getFontConfig( return ons_font::DEFAULT_FONT_CONFIG(); } -void ScriptParser::setFontConfig(const char *buf) { +int ScriptParser::setFontConfig(const char *buf) { ons_font::FONT_TYPE types = ons_font::GLOBAL_FONT; int offset = 0; if (buf[offset] >= '0' && buf[offset] <= '9') { @@ -130,7 +130,7 @@ void ScriptParser::setFontConfig(const char *buf) { } offset++; if (buf[offset] != ':') { - return; + return 0; } offset++; ons_font::FontConfig *cfg = nullptr; @@ -138,56 +138,7 @@ void ScriptParser::setFontConfig(const char *buf) { font_configs[types] = new ons_font::FontConfig; } cfg = font_configs[types]; - auto default_config = ons_font::DEFAULT_FONT_CONFIG(); - memcpy(cfg, default_config, sizeof(ons_font::FontConfig)); - int start = offset; - int field = 0; - char buff[256]; - while (1) { - if (buf[offset] == ',' || buf[offset] == '\0') { - int size = offset - start; - if (size > 0) { - memcpy(buff, buf + start, size); - buff[size] = '\0'; - } else { - buff[0] = '\0'; - } - start = offset + 1; - if (buff[0] != '\0') { - switch (field) { - case 0: - cfg->size = atoi(buff); - break; - case 1: - cfg->size_ratio = atof(buff); - break; - case 2: - readColor(&cfg->color, buff); - break; - case 3: - cfg->render_outline = buff[0] != '0' && buff[0] != 'f'; - break; - case 4: - cfg->outline_size = atoi(buff); - break; - case 5: - readColor(&cfg->outline_color, buff); - break; - case 6: - cfg->offset_x = atoi(buff); - break; - case 7: - cfg->offset_y = atoi(buff); - break; - } - } - field++; - } - if (buf[offset] == '\0') { - break; - } - offset++; - } + return ons_font::readFontConfig(buf, cfg); } const int ScriptParser::calcFontSize(const int v, ons_font::FONT_TYPE types) { @@ -397,6 +348,12 @@ int ScriptParser::openScript() { if (!init_screen_ratio) { *screen_scale = script_h.screen_scale; } + for (int i = 0; i < 6; i++) { + if (script_h.font_configs[i] != nullptr && font_configs[i] == nullptr) { + font_configs[i] = new ons_font::FontConfig{0}; + memcpy(font_configs[i], script_h.font_configs[i], sizeof(ons_font::FontConfig)); + } + } return 0; } diff --git a/src/ScriptParser.h b/src/ScriptParser.h index 119fb21..7accf64 100644 --- a/src/ScriptParser.h +++ b/src/ScriptParser.h @@ -179,7 +179,7 @@ class ScriptParser { int addCommand(); int elseCommand(); void setRescale(int scale1, int scale2); - void setFontConfig(const char *buf); + int setFontConfig(const char *buf); protected: struct UserFuncLUT { diff --git a/src/onscripter/ONScripter_text.cpp b/src/onscripter/ONScripter_text.cpp index a52634e..408e021 100644 --- a/src/onscripter/ONScripter_text.cpp +++ b/src/onscripter/ONScripter_text.cpp @@ -118,7 +118,11 @@ void ONScripter::drawGlyph(SDL_Surface *dst_surface, (TTF_Font *)info->ttf_font[0], unicode, fcol, bcol); const ons_font::FontConfig *cfg = getFontConfig(info->types); SDL_Color scolor = { - cfg->outline_color[0], cfg->outline_color[1], cfg->outline_color[2]}; + cfg->outline_color.rgba[0], + cfg->outline_color.rgba[1], + cfg->outline_color.rgba[2], + cfg->outline_color.rgba[3], + }; SDL_Surface *tmp_surface_s = tmp_surface; if (info->is_shadow && fontConfig->render_outline) { tmp_surface_s = TTF_RenderGlyph_Shaded(