From ff0c6a5ed8722212be952c2764fd92e34e825816 Mon Sep 17 00:00:00 2001 From: Laurent Date: Sat, 7 Nov 2026 15:14:12 +0100 Subject: [PATCH 2/2] Add --FixFonts: replace fonts that are not Liberation fonts Users send elements for the collection with fonts QET does not ship: Arial, Times New Roman, Courier New, Sans Serif, MS Shell Dlg 2... On a system without them the text looks different or is replaced. --FixFonts replaces the family of every text and dynamic_text font that is not a Liberation font by Liberation Sans, Serif or Mono, keeping the size and the rest of Qt's font string. Nothing is scaled or moved. Each change is listed on stderr. A changed element gets a new UUID so that projects take the new definition; an element needing no change is not rewritten, so the option can be run on a whole folder: find . -name "*.elmt" -exec QET_ElementScaler --FixFonts --OverwriteOriginal {} \; --- README.md | 8 +++++++ main.cpp | 29 ++++++++++++++++++++++++- main.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bee2f5..b1171d0 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,19 @@ QET_ElementScaler [options] <file>
(useful during creation of elements) "--OnlyCleanMeta" NO scaling or moving - sort names and delete empty elementInformation + "--FixFonts" NO scaling or moving - replace every font that + is not a Liberation font by Liberation Sans, + Serif or Mono and give the element a new UUID; + a file needing no change is left untouched "--OverwriteOriginal" the original file is replaced by scaled one (CAUTION: Be careful with this option!) ``` +
+replace the fonts of all elements in a folder by Liberation fonts +(each change is listed, unchanged files are not rewritten):
+find . -name "*.elmt" -exec QET_ElementScaler --FixFonts --OverwriteOriginal {} \;

examples to use data from stdin:
QET_ElementScaler -i -F 2.0 < ElementToScale.elmt > ScaledElement.elmt
diff --git a/main.cpp b/main.cpp index dd9248d..d97f0d6 100644 --- a/main.cpp +++ b/main.cpp @@ -119,6 +119,20 @@ int main(int argc, char **argv) return -2; } + // only replace the fonts: nothing else of the element changes + int iFontsFixed = 0; + if (xFixFonts == true) { + if (!xIsElmtFile) { + std::cerr << "--FixFonts works on element files only!\n"; + return -2; + } + iFontsFixed = FixFonts(doc); + if (iFontsFixed == 0 && xPrintToStdOut == false) { + // nothing to fix: leave the file as it is, no ".SCALED" copy + return 0; + } + } + // build the filename for the scaled element: ElementFileScaled = ElementFile; if (xOverwriteOriginal == true){ @@ -141,7 +155,20 @@ int main(int argc, char **argv) // Process the Element-file: scale, flip, etc... if (xIsElmtFile) { - ProcessElement(doc); + if (xFixFonts == true) { + if (iFontsFixed > 0) { + // a changed element needs a new UUID, so that projects using + // it take the new definition instead of their embedded copy + pugi::xml_node uuid = doc.child("definition").child("uuid"); + if (!uuid) { + uuid = doc.child("definition").prepend_child("uuid"); + uuid.append_attribute("uuid"); + } + uuid.attribute("uuid").set_value(("{" + CreateUUID(false) + "}").c_str()); + } + } else { + ProcessElement(doc); + } } if (xCreateSVG == true) { diff --git a/main.h b/main.h index 1f8073f..a7ed2ce 100644 --- a/main.h +++ b/main.h @@ -38,6 +38,7 @@ #include // for Commandline-Parameters #include // for exe-filename #include // for list of UUIDs +#include // for tolower // project-includes #include "inc/pugixml/pugixml.hpp" #include "inc/helpers.h" @@ -74,6 +75,7 @@ static bool xFlipHor = false; static bool xFlipVert = false; static bool xRotate90 = false; static bool xOnlyCleanMeta = false; +static bool xFixFonts = false; // to find out, if we need to renew UUIDs for "dynamic_text" or "terminal": static std::list lsUUIDsDynTexts; @@ -100,6 +102,7 @@ bool CheckUUIDs(void); void ProcessDirFile(pugi::xml_node); void ProcessElement(pugi::xml_node); std::string ToSVG(pugi::xml_node); +int FixFonts(pugi::xml_node); // the possible Commandlineparameters: static const char cOptions[] = "f:hioF:x:y:X:Y:d:"; @@ -122,6 +125,7 @@ static struct option long_options[]={ {"toSVG",no_argument,nullptr,1004}, // "long-opt" only!!! {"Rot90",no_argument,nullptr,1005}, // "long-opt" only!!! {"OnlyCleanMeta",no_argument,nullptr,1006}, // "long-opt" only!!! + {"FixFonts",no_argument,nullptr,1007}, // "long-opt" only!!! {0,0,0,0} }; @@ -195,6 +199,15 @@ int parseCommandline(int argc, char *argv[]) { xCreateELMT = true; } break; + case 1007: + if (std::string(long_options[option_index].name) == "FixFonts"){ + if (_DEBUG_) + std::cerr << "NO scaling or moving - replace fonts by Liberation fonts\n"; + xFixFonts = true; + xCreateSVG = false; // the element itself is rewritten + xCreateELMT = true; + } + break; case 'd': sTmp = std::string(optarg); CheckForDoubleString(sTmp); @@ -379,6 +392,10 @@ void PrintHelp(const std::string &s, const std::string &v){ << " (useful during creation of elements) \n" << " \"--OnlyCleanMeta\" NO scaling or moving - sort names and \n" << " delete empty elementInformation \n" + << " \"--FixFonts\" NO scaling or moving - replace every font that \n" + << " is not a Liberation font by Liberation Sans, \n" + << " Serif or Mono and give the element a new UUID; \n" + << " a file needing no change is left untouched \n" << " \"--OverwriteOriginal\" the original file is replaced by scaled one \n" << " (CAUTION: Be careful with this option!) \n" << std::endl @@ -389,6 +406,54 @@ void PrintHelp(const std::string &s, const std::string &v){ +/******************************************************************************/ +// The Liberation family standing in for a font family of an element: +// QET ships the Liberation fonts and uses them by default, so a text in +// any other font looks different, or is replaced, on a system without it. +std::string LiberationFamily(const std::string &family) { + std::string f = family; + for (auto &c : f) c = std::tolower(static_cast(c)); + auto has = [&f](const char *s) { return f.find(s) != std::string::npos; }; + if (has("mono") || has("courier") || has("console") || has("consolas") + || has("fixed") || has("cousine") || has("terminal")) + return "Liberation Mono"; + if ((has("serif") && !has("sans")) || has("times") || has("tinos") + || has("georgia") || has("cambria") || has("garamond")) + return "Liberation Serif"; + return "Liberation Sans"; +} +/******************************************************************************/ + + + +/******************************************************************************/ +// Replace the family of every font of the element's texts that is not a +// Liberation font, keeping the size and the rest of Qt's font string. +// Returns how many fonts were changed; each change is listed on stderr. +int FixFonts(pugi::xml_node doc) { + int changed = 0; + pugi::xml_node desc = doc.child("definition").child("description"); + for (pugi::xml_node node : desc.children()) { + pugi::xml_attribute font = node.attribute("font"); + if (!font) continue; + std::string value = font.as_string(); + size_t comma = value.find(','); + std::string family = value.substr(0, comma); + if (family.empty() || family.rfind("Liberation ", 0) == 0) continue; + std::string target = LiberationFamily(family); + std::string rest = (comma == std::string::npos) ? "" : value.substr(comma); + font.set_value((target + rest).c_str()); + std::cerr << (ElementFile.empty() ? std::string("stdin") : ElementFile) + << ": " << node.name() << " \"" << family + << "\" -> \"" << target << "\"\n"; + ++changed; + } + return changed; +} +/******************************************************************************/ + + + /******************************************************************************/ bool CheckUUIDs(void) { uint64_t u64DynTextsOrg = lsUUIDsDynTexts.size(); -- 2.43.0