From 17d3c756c743accf2af690075a337acf2c302bf8 Mon Sep 17 00:00:00 2001 From: Dav999-v Date: Mon, 23 Jan 2023 03:15:17 +0100 Subject: [PATCH] Write max_local to language files during sync If your language has a bigger font, the max attribute isn't really helpful to you as a translator, so the sync feature adds a special max_local attribute which is accurate to the font size. This was already documented in advance. If used, we now also write an attribute in the root tag of strings.xml and strings_plural.xml, that looks like max_local_for="12x12". I decided to add this attribute after finding out the Excel macros would be really hard to change to only show a max_local column if it is ever used (it'd need to look ahead through the strings until it finds a string with a max, or remove the column if no string has used it), but it's also a convenience for translators. --- desktop_version/src/LocalizationMaint.cpp | 61 +++++++++++++++++++++ desktop_version/src/LocalizationStorage.cpp | 2 +- desktop_version/src/LocalizationStorage.h | 2 + 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/desktop_version/src/LocalizationMaint.cpp b/desktop_version/src/LocalizationMaint.cpp index 5f0a7689..3621735b 100644 --- a/desktop_version/src/LocalizationMaint.cpp +++ b/desktop_version/src/LocalizationMaint.cpp @@ -16,6 +16,43 @@ namespace loc { +static void write_max_local(tinyxml2::XMLElement* pElem, uint8_t glyph_w, uint8_t glyph_h) +{ + const char* max; + if ((max = pElem->Attribute("max")) != NULL) + { + unsigned short max_w, max_h, max_local_w, max_local_h; + if (parse_max(max, &max_w, &max_h)) + { + max_local_w = (max_w*8) / glyph_w; + max_local_h = (max_h*10) / SDL_max(10, glyph_h); + + if (max_local_h == 0) + { + max_local_h = 1; + } + + char buf[16]; + if (max_h == 1) + { + SDL_snprintf(buf, sizeof(buf), "%d", max_local_w); + } + else + { + SDL_snprintf(buf, sizeof(buf), "%d*%d", max_local_w, max_local_h); + } + pElem->SetAttribute("max_local", buf); + } + } +} + +static void write_max_local_decl(tinyxml2::XMLDocument* doc, uint8_t glyph_w, uint8_t glyph_h) +{ + char buf[16]; + SDL_snprintf(buf, sizeof(buf), "%dx%d", glyph_w, glyph_h); + doc->FirstChildElement()->SetAttribute("max_local_for", buf); +} + static void sync_lang_file(const std::string& langcode) { /* Update translation files for the given language with new strings from templates. @@ -26,6 +63,10 @@ static void sync_lang_file(const std::string& langcode) lang = langcode; loadtext(false); + uint8_t glyph_w = 8, glyph_h = 8; + font::glyph_dimensions(PR_FONT_IDX(langmeta.font_idx), &glyph_w, &glyph_h); + bool max_local_needed = glyph_w != 8 || glyph_h != 8; + tinyxml2::XMLDocument doc; tinyxml2::XMLHandle hDoc(&doc); tinyxml2::XMLElement* pElem; @@ -86,6 +127,11 @@ static void sync_lang_file(const std::string& langcode) if (load_lang_doc("strings", doc, "en")) { + if (max_local_needed) + { + write_max_local_decl(&doc, glyph_w, glyph_h); + } + FOR_EACH_XML_ELEMENT(hDoc, pElem) { EXPECT_ELEM(pElem, "string"); @@ -119,6 +165,11 @@ static void sync_lang_file(const std::string& langcode) pElem->SetAttribute("translation", tra); } + + if (max_local_needed) + { + write_max_local(pElem, glyph_w, glyph_h); + } } FILESYSTEM_saveTiXml2Document((langcode + "/strings.xml").c_str(), doc); @@ -134,10 +185,20 @@ static void sync_lang_file(const std::string& langcode) form_id_used[number_plural_form[num]] = true; } + if (max_local_needed) + { + write_max_local_decl(&doc, glyph_w, glyph_h); + } + FOR_EACH_XML_ELEMENT(hDoc, pElem) { EXPECT_ELEM(pElem, "string"); + if (max_local_needed) + { + write_max_local(pElem, glyph_w, glyph_h); + } + pElem->DeleteChildren(); const char* eng_plural = pElem->Attribute("english_plural"); diff --git a/desktop_version/src/LocalizationStorage.cpp b/desktop_version/src/LocalizationStorage.cpp index 1a7d5df8..f0835a6f 100644 --- a/desktop_version/src/LocalizationStorage.cpp +++ b/desktop_version/src/LocalizationStorage.cpp @@ -252,7 +252,7 @@ void resettext(bool final_shutdown) resettext_custom(final_shutdown); } -static bool parse_max(const char* max, unsigned short* max_w, unsigned short* max_h) +bool parse_max(const char* max, unsigned short* max_w, unsigned short* max_h) { /* Parse a max string, like "33" or "33*3", into two shorts. * Returns true if successful and max_w/max_h have gotten valid values, false otherwise. */ diff --git a/desktop_version/src/LocalizationStorage.h b/desktop_version/src/LocalizationStorage.h index 5263e1de..5d9172e5 100644 --- a/desktop_version/src/LocalizationStorage.h +++ b/desktop_version/src/LocalizationStorage.h @@ -68,6 +68,8 @@ unsigned char form_for_count(int n); void unloadtext_custom(void); void resettext(bool final_shutdown); +bool parse_max(const char* max, unsigned short* max_w, unsigned short* max_h); + const char* get_level_original_lang(tinyxml2::XMLHandle& hDoc); bool store_roomname_translation(bool custom_level, int roomx, int roomy, const char* tra, const char* explanation);