mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-03 10:34:14 +02:00
Write font descriptions in the stable Qt 5 10/11-field format
QFont::toString() is not stable across Qt versions: Qt 6.11 switched to a 19-field format carrying OpenType weights, which QFont::fromString() of Qt 5.x and Qt <= 6.10 rejects, leaving a broken font. Projects saved by a Qt 6.11+ build were therefore unreadable by older builds. Add QETUtils::fontToString() composing the legacy 10/11-field description (weight mapped back to the legacy scale with the same closest-match table Qt uses when parsing) and use it at every site that stores a font description in a project, element, table config or settings file. Every Qt version from 5.15 through 6.12-beta parses this form correctly, so files stay readable by every QET build in circulation. See issue #553.
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include "../../QPropertyUndoCommand/qpropertyundocommand.h"
|
#include "../../QPropertyUndoCommand/qpropertyundocommand.h"
|
||||||
#include "../../qetapp.h"
|
#include "../../qetapp.h"
|
||||||
#include "../elementscene.h"
|
#include "../elementscene.h"
|
||||||
|
#include "../../utils/qetutils.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
@@ -142,7 +143,7 @@ const QDomElement PartDynamicTextField::toXml(QDomDocument &dom_doc) const
|
|||||||
root_element.setAttribute("y", QString::number(y));
|
root_element.setAttribute("y", QString::number(y));
|
||||||
root_element.setAttribute("z", QString::number(zValue()));
|
root_element.setAttribute("z", QString::number(zValue()));
|
||||||
root_element.setAttribute("rotation", QString::number(QET::correctAngle(rot)));
|
root_element.setAttribute("rotation", QString::number(QET::correctAngle(rot)));
|
||||||
root_element.setAttribute("font", font().toString());
|
root_element.setAttribute("font", QETUtils::fontToString(font()));
|
||||||
root_element.setAttribute("uuid", m_uuid.toString());
|
root_element.setAttribute("uuid", m_uuid.toString());
|
||||||
root_element.setAttribute("frame", m_frame? "true" : "false");
|
root_element.setAttribute("frame", m_frame? "true" : "false");
|
||||||
root_element.setAttribute("text_width", QString::number(m_text_width));
|
root_element.setAttribute("text_width", QString::number(m_text_width));
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "../elementprimitivedecorator.h"
|
#include "../elementprimitivedecorator.h"
|
||||||
#include "../elementscene.h"
|
#include "../elementscene.h"
|
||||||
#include "../ui/texteditor.h"
|
#include "../ui/texteditor.h"
|
||||||
|
#include "../../utils/qetutils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructeur
|
Constructeur
|
||||||
@@ -165,7 +166,7 @@ const QDomElement PartText::toXml(QDomDocument &xml_document) const
|
|||||||
xml_element.setAttribute("x", QString::number(x));
|
xml_element.setAttribute("x", QString::number(x));
|
||||||
xml_element.setAttribute("y", QString::number(y));
|
xml_element.setAttribute("y", QString::number(y));
|
||||||
xml_element.setAttribute("text", toPlainText());
|
xml_element.setAttribute("text", toPlainText());
|
||||||
xml_element.setAttribute("font", font().toString());
|
xml_element.setAttribute("font", QETUtils::fontToString(font()));
|
||||||
xml_element.setAttribute("rotation", QString::number(rot));
|
xml_element.setAttribute("rotation", QString::number(rot));
|
||||||
xml_element.setAttribute("color", defaultTextColor().name());
|
xml_element.setAttribute("color", defaultTextColor().name());
|
||||||
|
|
||||||
|
|||||||
@@ -221,12 +221,12 @@ void AddTableDialog::saveConfig()
|
|||||||
header_object.insert("margins", QETUtils::marginsToString(this->headerMargins()));
|
header_object.insert("margins", QETUtils::marginsToString(this->headerMargins()));
|
||||||
auto me = QMetaEnum::fromType<Qt::Alignment>();
|
auto me = QMetaEnum::fromType<Qt::Alignment>();
|
||||||
header_object.insert("alignment", me.valueToKey(int(this->headerAlignment())));
|
header_object.insert("alignment", me.valueToKey(int(this->headerAlignment())));
|
||||||
header_object.insert("font", this->headerFont().toString());
|
header_object.insert("font", QETUtils::fontToString(this->headerFont()));
|
||||||
|
|
||||||
QJsonObject table_object;
|
QJsonObject table_object;
|
||||||
table_object.insert("margins", QETUtils::marginsToString(this->tableMargins()));
|
table_object.insert("margins", QETUtils::marginsToString(this->tableMargins()));
|
||||||
table_object.insert("alignment", me.valueToKey(int(this->tableAlignment())));
|
table_object.insert("alignment", me.valueToKey(int(this->tableAlignment())));
|
||||||
table_object.insert("font", this->tableFont().toString());
|
table_object.insert("font", QETUtils::fontToString(this->tableFont()));
|
||||||
|
|
||||||
QJsonObject config_object;
|
QJsonObject config_object;
|
||||||
config_object.insert("header", header_object);
|
config_object.insert("header", header_object);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
#include "terminaldata.h"
|
#include "terminaldata.h"
|
||||||
|
|
||||||
|
#include "../utils/qetutils.h"
|
||||||
|
|
||||||
#include <QGraphicsObject>
|
#include <QGraphicsObject>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -115,7 +117,7 @@ QDomElement TerminalData::toXml(QDomDocument &xml_document) const
|
|||||||
xml_element.setAttribute("show_name", "true");
|
xml_element.setAttribute("show_name", "true");
|
||||||
xml_element.setAttribute("label_x", QString::number(m_label_pos.x()));
|
xml_element.setAttribute("label_x", QString::number(m_label_pos.x()));
|
||||||
xml_element.setAttribute("label_y", QString::number(m_label_pos.y()));
|
xml_element.setAttribute("label_y", QString::number(m_label_pos.y()));
|
||||||
xml_element.setAttribute("label_font", m_label_font.toString());
|
xml_element.setAttribute("label_font", QETUtils::fontToString(m_label_font));
|
||||||
xml_element.setAttribute("label_rotation", QString::number(m_label_rotation));
|
xml_element.setAttribute("label_rotation", QString::number(m_label_rotation));
|
||||||
xml_element.setAttribute("label_halign", static_cast<int>(m_label_halignment));
|
xml_element.setAttribute("label_halign", static_cast<int>(m_label_halignment));
|
||||||
xml_element.setAttribute("label_valign", static_cast<int>(m_label_valignment));
|
xml_element.setAttribute("label_valign", static_cast<int>(m_label_valignment));
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "../../qetinformation.h"
|
#include "../../qetinformation.h"
|
||||||
#include "../../qetproject.h"
|
#include "../../qetproject.h"
|
||||||
#include "../../qetxml.h"
|
#include "../../qetxml.h"
|
||||||
|
#include "../../utils/qetutils.h"
|
||||||
|
|
||||||
#include <QSqlError>
|
#include <QSqlError>
|
||||||
#include <QSqlRecord>
|
#include <QSqlRecord>
|
||||||
@@ -252,7 +253,7 @@ QDomElement ProjectDBModel::toXml(QDomDocument &document) const
|
|||||||
|
|
||||||
//Add index 0,0 data
|
//Add index 0,0 data
|
||||||
auto index_00 = document.createElement("index00");
|
auto index_00 = document.createElement("index00");
|
||||||
index_00.setAttribute("font", m_index_0_0_data.value(Qt::FontRole).toString());
|
index_00.setAttribute("font", QETUtils::fontToString(m_index_0_0_data.value(Qt::FontRole).value<QFont>()));
|
||||||
auto me = QMetaEnum::fromType<Qt::Alignment>();
|
auto me = QMetaEnum::fromType<Qt::Alignment>();
|
||||||
index_00.setAttribute("alignment", me.valueToKey(m_index_0_0_data.value(Qt::TextAlignmentRole).toInt()));
|
index_00.setAttribute("alignment", me.valueToKey(m_index_0_0_data.value(Qt::TextAlignmentRole).toInt()));
|
||||||
dom_element.appendChild(index_00);
|
dom_element.appendChild(index_00);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "../qetgraphicsitem/conductor.h"
|
#include "../qetgraphicsitem/conductor.h"
|
||||||
#include "../qetgraphicsitem/terminal.h"
|
#include "../qetgraphicsitem/terminal.h"
|
||||||
#include "../qetinformation.h"
|
#include "../qetinformation.h"
|
||||||
|
#include "../utils/qetutils.h"
|
||||||
#include "crossrefitem.h"
|
#include "crossrefitem.h"
|
||||||
#include "element.h"
|
#include "element.h"
|
||||||
#include "elementtextitemgroup.h"
|
#include "elementtextitemgroup.h"
|
||||||
@@ -96,7 +97,7 @@ QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
|
|||||||
root_element.setAttribute("uuid", m_uuid.toString());
|
root_element.setAttribute("uuid", m_uuid.toString());
|
||||||
root_element.setAttribute("frame", m_frame? "true" : "false");
|
root_element.setAttribute("frame", m_frame? "true" : "false");
|
||||||
root_element.setAttribute("text_width", QString::number(m_text_width));
|
root_element.setAttribute("text_width", QString::number(m_text_width));
|
||||||
root_element.setAttribute("font", font().toString());
|
root_element.setAttribute("font", QETUtils::fontToString(font()));
|
||||||
root_element.setAttribute("keep_visual_rotation", m_keep_visual_rotation ? "true" : "false");
|
root_element.setAttribute("keep_visual_rotation", m_keep_visual_rotation ? "true" : "false");
|
||||||
|
|
||||||
QMetaEnum me = textFromMetaEnum();
|
QMetaEnum me = textFromMetaEnum();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "../diagramcommands.h"
|
#include "../diagramcommands.h"
|
||||||
#include "../qet.h"
|
#include "../qet.h"
|
||||||
#include "../qetapp.h"
|
#include "../qetapp.h"
|
||||||
|
#include "../utils/qetutils.h"
|
||||||
|
|
||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
@@ -80,7 +81,7 @@ QDomElement IndependentTextItem::toXml(QDomDocument &document) const
|
|||||||
result.setAttribute("y", QString("%1").arg(pos().y()));
|
result.setAttribute("y", QString("%1").arg(pos().y()));
|
||||||
result.setAttribute("text", toHtml());
|
result.setAttribute("text", toHtml());
|
||||||
result.setAttribute("rotation", QString::number(QET::correctAngle(rotation())));
|
result.setAttribute("rotation", QString::number(QET::correctAngle(rotation())));
|
||||||
result.setAttribute("font", font().toString());
|
result.setAttribute("font", QETUtils::fontToString(font()));
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@
|
|||||||
#include "qetxml.h"
|
#include "qetxml.h"
|
||||||
|
|
||||||
#include "NameList/nameslist.h"
|
#include "NameList/nameslist.h"
|
||||||
|
#include "utils/qetutils.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
@@ -477,7 +478,7 @@ QDomElement QETXML::modelHeaderDataToXml(
|
|||||||
else if (role == Qt::FontRole)
|
else if (role == Qt::FontRole)
|
||||||
{
|
{
|
||||||
auto font = variant.value<QFont>();
|
auto font = variant.value<QFont>();
|
||||||
text_node.setData(font.toString());
|
text_node.setData(QETUtils::fontToString(font));
|
||||||
}
|
}
|
||||||
else if (role == Qt::TextAlignmentRole)
|
else if (role == Qt::TextAlignmentRole)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "../../qeticons.h"
|
#include "../../qeticons.h"
|
||||||
#include "ui_generalconfigurationpage.h"
|
#include "ui_generalconfigurationpage.h"
|
||||||
#include "../../utils/qetsettings.h"
|
#include "../../utils/qetsettings.h"
|
||||||
|
#include "../../utils/qetutils.h"
|
||||||
#include "../../qetmessagebox.h"
|
#include "../../qetmessagebox.h"
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFontDialog>
|
#include <QFontDialog>
|
||||||
@@ -459,7 +460,7 @@ void GeneralConfigurationPage::on_m_dyn_text_font_pb_clicked()
|
|||||||
QFont font = QFontDialog::getFont(&ok, curFont, this);
|
QFont font = QFontDialog::getFont(&ok, curFont, this);
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
settings.setValue("diagrameditor/dynamic_text_font", font.toString());
|
settings.setValue("diagrameditor/dynamic_text_font", QETUtils::fontToString(font));
|
||||||
QString fontInfos = font.family() + " " +
|
QString fontInfos = font.family() + " " +
|
||||||
QString::number(font.pointSize()) + " (" +
|
QString::number(font.pointSize()) + " (" +
|
||||||
font.styleName() + ")";
|
font.styleName() + ")";
|
||||||
@@ -563,7 +564,7 @@ void GeneralConfigurationPage::on_m_indi_text_font_pb_clicked()
|
|||||||
QFont font = QFontDialog::getFont(&ok, curFont, this);
|
QFont font = QFontDialog::getFont(&ok, curFont, this);
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
settings.setValue("diagrameditor/independent_text_font", font.toString());
|
settings.setValue("diagrameditor/independent_text_font", QETUtils::fontToString(font));
|
||||||
QString fontInfos = font.family() + " " +
|
QString fontInfos = font.family() + " " +
|
||||||
QString::number(font.pointSize()) + " (" +
|
QString::number(font.pointSize()) + " (" +
|
||||||
font.styleName() + ")";
|
font.styleName() + ")";
|
||||||
|
|||||||
@@ -150,3 +150,59 @@ void QETUtils::pixelSizedFont(QFont &font)
|
|||||||
auto px = font.pointSizeF()/72 * QFontMetrics{font}.fontDpi();
|
auto px = font.pointSizeF()/72 * QFontMetrics{font}.fontDpi();
|
||||||
font.setPixelSize(qRound(px));
|
font.setPixelSize(qRound(px));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETUtils::fontToString
|
||||||
|
* Serialize a font to the 10/11 field description format written by Qt 5,
|
||||||
|
* to be used instead of QFont::toString() everywhere a font description is
|
||||||
|
* stored in a project, element or settings file.
|
||||||
|
* The format of QFont::toString() is not stable across Qt versions : Qt 6.11
|
||||||
|
* switched to a 19 field format carrying OpenType weights, which
|
||||||
|
* QFont::fromString() of Qt 5.x and Qt <= 6.10 rejects, leaving a broken font.
|
||||||
|
* The 10/11 field form is parsed correctly by every Qt version (they convert
|
||||||
|
* the legacy weight scale as needed), so composing it ourselves keeps files
|
||||||
|
* readable by every QET build in circulation.
|
||||||
|
* See @link https://github.com/qelectrotech/qelectrotech-source-mirror/issues/553 @endlink
|
||||||
|
* @param font
|
||||||
|
* @return the font description string
|
||||||
|
*/
|
||||||
|
QString QETUtils::fontToString(const QFont &font)
|
||||||
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
return font.toString();
|
||||||
|
#else
|
||||||
|
//Legacy (Qt 5) weight <- OpenType weight, closest match,
|
||||||
|
//same table Qt uses when parsing a 10/11 field string.
|
||||||
|
static const int weight_map[9][2] = {
|
||||||
|
{0, 100}, {12, 200}, {25, 300}, {50, 400}, {57, 500},
|
||||||
|
{63, 600}, {75, 700}, {81, 800}, {87, 900}
|
||||||
|
};
|
||||||
|
const int weight = font.weight();
|
||||||
|
int legacy_weight = weight_map[0][0];
|
||||||
|
int closest_diff = qAbs(weight - weight_map[0][1]);
|
||||||
|
for (int i = 1 ; i < 9 ; ++i)
|
||||||
|
{
|
||||||
|
const int diff = qAbs(weight - weight_map[i][1]);
|
||||||
|
if (diff < closest_diff) {
|
||||||
|
closest_diff = diff;
|
||||||
|
legacy_weight = weight_map[i][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QChar comma(QLatin1Char(','));
|
||||||
|
QString description = font.family() + comma +
|
||||||
|
QString::number(font.pointSizeF()) + comma +
|
||||||
|
QString::number(font.pixelSize()) + comma +
|
||||||
|
QString::number(int(font.styleHint())) + comma +
|
||||||
|
QString::number(legacy_weight) + comma +
|
||||||
|
QString::number(int(font.style())) + comma +
|
||||||
|
QString::number(int(font.underline())) + comma +
|
||||||
|
QString::number(int(font.strikeOut())) + comma +
|
||||||
|
QString::number(int(font.fixedPitch())) + comma +
|
||||||
|
QString::number(0);
|
||||||
|
if (!font.styleName().isEmpty()) {
|
||||||
|
description += QChar(',') + font.styleName();
|
||||||
|
}
|
||||||
|
return description;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace QETUtils
|
|||||||
QMargins marginsFromString(const QString &string);
|
QMargins marginsFromString(const QString &string);
|
||||||
qreal graphicsHandlerSize(QGraphicsItem *item);
|
qreal graphicsHandlerSize(QGraphicsItem *item);
|
||||||
void pixelSizedFont (QFont &font);
|
void pixelSizedFont (QFont &font);
|
||||||
|
QString fontToString (const QFont &font);
|
||||||
|
|
||||||
bool sortBeginIntString(const QString &str_a, const QString &str_b);
|
bool sortBeginIntString(const QString &str_a, const QString &str_b);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user