From f43b6002f4447bce683b33e9d1cdff1485fec6b5 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Fri, 17 Nov 2023 11:57:20 -0500 Subject: [PATCH] [TD]fix position of RTA on Svg export --- src/Mod/TechDraw/Gui/QGIRichAnno.cpp | 147 +++++++++++++++------------ src/Mod/TechDraw/Gui/QGIRichAnno.h | 7 +- 2 files changed, 87 insertions(+), 67 deletions(-) diff --git a/src/Mod/TechDraw/Gui/QGIRichAnno.cpp b/src/Mod/TechDraw/Gui/QGIRichAnno.cpp index f33ac921fb..be2278de6a 100644 --- a/src/Mod/TechDraw/Gui/QGIRichAnno.cpp +++ b/src/Mod/TechDraw/Gui/QGIRichAnno.cpp @@ -37,6 +37,7 @@ #include #include +#include #include "QGIRichAnno.h" #include "mrichtextedit.h" @@ -46,10 +47,12 @@ #include "Rez.h" #include "ViewProviderRichAnno.h" #include "ZVALUE.h" +#include "DrawGuiUtil.h" using namespace TechDraw; using namespace TechDrawGui; +using DU = DrawUtil; //************************************************************** @@ -142,83 +145,49 @@ void QGIRichAnno::draw() void QGIRichAnno::setTextItem() { -// Base::Console().Message("QGIRA::setTextItem() - %s\n", getViewName()); +// Base::Console().Message("QGIRA::setTextItem() - %s - exportingSvg: %d\n", getViewName(), getExportingSvg()); TechDraw::DrawRichAnno* annoFeat = getFeature(); + + // convert the text size QString inHtml = QString::fromUtf8(annoFeat->AnnoText.getValue()); - QRectF inRect = m_text->boundingRect(); - double fontSize = m_text->font().pointSizeF(); - - QRegularExpression rxFontSize(QString::fromUtf8("font-size:([0-9]*)pt;")); - QRegularExpressionMatch match; - double mmPerPoint = 0.353; // 25.4 mm/in / 72 points/inch - double cssPxPerPoint = 16.0 / 12.0; // CSS says 12 pt text is 16 px high - double sceneUnitsPerPoint = Rez::getRezFactor() * mmPerPoint; // scene units per point: 3.53 - int pos = 0; - QStringList findList; - QStringList replList; - while ((pos = inHtml.indexOf(rxFontSize, pos, &match)) != -1) { - QString found = match.captured(0); - findList << found; - QString qsOldSize = match.captured(1); - - QString repl = found; - double newSize = qsOldSize.toDouble(); // in points - // The font size in the QGraphicsTextItem html is interpreted differently - // in svg rendering compared to the screen or pdf? - if (getExportingSvg()) { - // scale point size to CSS pixels - newSize = newSize * cssPxPerPoint; - } else { - // scale point size to scene units - newSize = newSize * sceneUnitsPerPoint; - } - QString qsNewSize = QString::number(newSize, 'f', 2); - repl.replace(qsOldSize, qsNewSize); - replList << repl; - pos += match.capturedLength(); - } - QString outHtml = inHtml; - int iRepl = 0; - //TODO: check list for duplicates? - for ( ; iRepl < findList.size(); iRepl++) { - outHtml = outHtml.replace(findList[iRepl], replList[iRepl]); - } + QString outHtml = convertTextSizes(inHtml); + //position the text prepareGeometryChange(); - double actualWidth = m_text->textWidth(); - m_text->setTextWidth(Rez::guiX(annoFeat->MaxWidth.getValue())); + // control auto line break + if (annoFeat->MaxWidth.getValue() > 0.0) { + // we have set a maximum width, so convert it to scene units + m_text->setTextWidth(Rez::guiX(annoFeat->MaxWidth.getValue())); + } else { + // we don't want to break lines + m_text->setTextWidth(annoFeat->MaxWidth.getValue()); + } m_text->setHtml(outHtml); if (getExportingSvg()) { - m_text->setTextWidth(actualWidth); // lines are correctly spaced on screen or in pdf, but svg needs this setLineSpacing(100); } - if (annoFeat->ShowFrame.getValue()) { - QRectF outRect = m_text->boundingRect().adjusted(1, 1,-1, -1); - m_rect->setPen(rectPen()); - m_rect->setBrush(Qt::NoBrush); + if (!getExportingSvg()) { + // screen or pdf rendering + m_text->centerAt(0.0, 0.0); + } + + // align the frame rectangle to the text + constexpr double frameMargin{10.0}; + QRectF outRect = m_text->boundingRect().adjusted(-frameMargin, -frameMargin, frameMargin, frameMargin); + m_rect->setPen(rectPen()); + m_rect->setBrush(Qt::NoBrush); + if (!getExportingSvg()) { m_rect->setRect(outRect); - if (getExportingSvg()) { - // the original text bounding rect is closer to the right size vs - // the bounding rect after the text size is changed - m_rect->setRect(inRect); - } - m_rect->centerAt(0.0, 0.0); + m_rect->setPos(m_text->pos().x() - frameMargin, m_text->pos().y() - frameMargin); + } + + if (annoFeat->ShowFrame.getValue()) { m_rect->show(); } else { m_rect->hide(); } - - m_text->centerAt(0.0, 0.0); - if (getExportingSvg()) { - // m_text position will be wrong in svg, but m_rect will be correct, so - // we adjust the position of m_text - // double spaced default font size in px - double verticalAdjust = cssPxPerPoint * fontSize * 2.0; - QPointF textPos(m_rect->pos().x() + 1.0, m_rect->pos().y() + verticalAdjust); - m_text->setPos(textPos); - } } // attempt to space the lines correctly after the font sizes are changed to match @@ -261,6 +230,53 @@ void QGIRichAnno::setLineSpacing(int lineSpacing) } } +//! convert the word processing font size spec (in typographic points) to scene units for the screen or +//! pdf rendering or to CSS pixels for Svg rendering +QString QGIRichAnno::convertTextSizes(const QString& inHtml) const +{ + constexpr double mmPerPoint{0.353}; // 25.4 mm/in / 72 points/inch + constexpr double cssPxPerPoint{1.333333}; // CSS says 12 pt text is 16 px high + double sceneUnitsPerPoint = Rez::getRezFactor() * mmPerPoint; // scene units per point: 3.53 + + QRegularExpression rxFontSize(QString::fromUtf8("font-size:([0-9]*)pt;")); + QRegularExpressionMatch match; + QStringList findList; + QStringList replList; + + // find each occurence of "font-size:..." and calculate the equivalent size in scene units + // or CSS pixels + int pos = 0; + while ((pos = inHtml.indexOf(rxFontSize, pos, &match)) != -1) { + QString found = match.captured(0); + findList << found; + QString qsOldSize = match.captured(1); + + QString repl = found; + double newSize = qsOldSize.toDouble(); // in points + // The font size in the QGraphicsTextItem html is interpreted differently + // in QSvgRenderer rendering compared to painting the screen or pdf + if (getExportingSvg()) { + // scale point size to CSS pixels + newSize = newSize * cssPxPerPoint; + } else { + // scale point size to scene units + newSize = newSize * sceneUnitsPerPoint; + } + QString qsNewSize = QString::number(newSize, 'f', 2); + repl.replace(qsOldSize, qsNewSize); + replList << repl; + pos += match.capturedLength(); + } + QString outHtml = inHtml; + int iRepl = 0; + //TODO: check list for duplicates? + for ( ; iRepl < findList.size(); iRepl++) { + outHtml = outHtml.replace(findList[iRepl], replList[iRepl]); + } + + return outHtml; +} + TechDraw::DrawRichAnno* QGIRichAnno::getFeature() { TechDraw::DrawRichAnno* result = @@ -268,16 +284,17 @@ TechDraw::DrawRichAnno* QGIRichAnno::getFeature() return result; } + +// TODO: this rect is the right size, but not in the right place QRectF QGIRichAnno::boundingRect() const { - QRectF rect = mapFromItem(m_text, m_text->boundingRect()).boundingRect(); - return rect.adjusted(-10., -10., 10., 10.); + return m_text->boundingRect() | m_rect->boundingRect(); } void QGIRichAnno::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) { QStyleOptionGraphicsItem myOption(*option); myOption.state &= ~QStyle::State_Selected; - +// painter->setPen(Qt::blue); // painter->drawRect(boundingRect()); //good for debugging QGIView::paint (painter, &myOption, widget); diff --git a/src/Mod/TechDraw/Gui/QGIRichAnno.h b/src/Mod/TechDraw/Gui/QGIRichAnno.h index bc6d70d96e..1363584c25 100644 --- a/src/Mod/TechDraw/Gui/QGIRichAnno.h +++ b/src/Mod/TechDraw/Gui/QGIRichAnno.h @@ -65,6 +65,7 @@ public: const QStyleOptionGraphicsItem * option, QWidget * widget = nullptr ) override; QRectF boundingRect() const override; + QRectF frameRect() const; void drawBorder() override; void updateView(bool update = false) override; @@ -75,9 +76,9 @@ public: QPen rectPen() const; void setExportingPdf(bool b) { m_isExportingPdf = b; } - bool getExportingPdf() { return m_isExportingPdf; } + bool getExportingPdf() const { return m_isExportingPdf; } void setExportingSvg(bool b) { m_isExportingSvg = b; } - bool getExportingSvg() { return m_isExportingSvg; } + bool getExportingSvg() const { return m_isExportingSvg; } protected: void draw() override; @@ -86,6 +87,8 @@ protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; + QString convertTextSizes(const QString& inHtml) const; + bool m_isExportingPdf; bool m_isExportingSvg; QGCustomText* m_text;