From e4481754f01c3b5d5e87e30c1806dec40be74237 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Fri, 12 Apr 2024 09:51:49 +0300 Subject: [PATCH] Fix calculating label position for flipped piece. --- src/app/puzzle/scene/vpgraphicspiece.cpp | 46 +----------------- src/libs/vdxf/vdxfengine.cpp | 39 +-------------- src/libs/vhpgl/vhpglengine.cpp | 41 +--------------- src/libs/vlayout/vlayoutpiece.cpp | 36 +++++++++++++- src/libs/vlayout/vlayoutpiece.h | 3 ++ src/libs/vlayout/vtextmanager.cpp | 61 ------------------------ src/libs/vlayout/vtextmanager.h | 3 -- 7 files changed, 43 insertions(+), 186 deletions(-) diff --git a/src/app/puzzle/scene/vpgraphicspiece.cpp b/src/app/puzzle/scene/vpgraphicspiece.cpp index e4b71f716..7a0b32f98 100644 --- a/src/app/puzzle/scene/vpgraphicspiece.cpp +++ b/src/app/puzzle/scene/vpgraphicspiece.cpp @@ -72,46 +72,6 @@ QT_WARNING_POP namespace { -//--------------------------------------------------------------------------------------------------------------------- -inline auto LineMatrix(const VPPiecePtr &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos, - int maxLineWidth) -> QTransform -{ - if (piece.isNull()) - { - return {}; - } - - QTransform labelMatrix; - labelMatrix.translate(topLeft.x(), topLeft.y()); - - if ((piece->IsVerticallyFlipped() && piece->IsHorizontallyFlipped()) || - (!piece->IsVerticallyFlipped() && !piece->IsHorizontallyFlipped())) - { - labelMatrix.rotate(angle); - } - else if (piece->IsVerticallyFlipped() || piece->IsHorizontallyFlipped()) - { - if (piece->IsVerticallyFlipped() && !piece->IsHorizontallyFlipped()) - { - labelMatrix.scale(-1, 1); - labelMatrix.rotate(-angle); - labelMatrix.translate(-maxLineWidth, 0); - } - - if (piece->IsHorizontallyFlipped() && !piece->IsVerticallyFlipped()) - { - labelMatrix.scale(-1, 1); - labelMatrix.rotate(-angle); - labelMatrix.translate(-maxLineWidth, 0); - } - } - - labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position - labelMatrix *= piece->GetMatrix(); - - return labelMatrix; -} - //--------------------------------------------------------------------------------------------------------------------- inline auto LineFont(const TextLine &tl, const QFont &base) -> QFont { @@ -448,7 +408,6 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector &labelShape, const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length(); const qreal angle = -QLineF(labelShape.at(0), labelShape.at(1)).angle(); const QColor color = PieceColor(); - const int maxLineWidth = tm.MaxLineWidthSVGFont(static_cast(dW), penWidth); qreal dY = penWidth; @@ -467,7 +426,7 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector &labelShape, const QString qsText = tl.m_qsText; const qreal dX = LineAlign(tl, qsText, engine, dW, penWidth); // set up the rotation around top-left corner matrix - const QTransform lineMatrix = LineMatrix(piece, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth); + const QTransform lineMatrix = piece->LineMatrix(labelShape.at(0), angle, QPointF(dX, dY), dW); auto *item = new QGraphicsPathItem(this); item->setPath(engine.DrawPath(QPointF(), qsText)); @@ -505,7 +464,6 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector &labelSha const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length(); const qreal angle = -QLineF(labelShape.at(0), labelShape.at(1)).angle(); const QColor color = PieceColor(); - const int maxLineWidth = tm.MaxLineWidthOutlineFont(static_cast(dW)); qreal const penWidth = VPApplication::VApp()->PuzzleSettings()->GetLayoutLineWidth(); qreal dY = 0; @@ -533,7 +491,7 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector &labelSha const qreal dX = LineAlign(tl, tl.m_qsText, fm, dW); // set up the rotation around top-left corner matrix - const QTransform lineMatrix = LineMatrix(piece, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth); + const QTransform lineMatrix = piece->LineMatrix(labelShape.at(0), angle, QPointF(dX, dY), dW); if (textAsPaths) { diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index 142f8dbda..bbe5214f3 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -153,42 +153,6 @@ inline auto LineAlign(const TextLine &tl, const QString &text, const QFontMetric return dX; } - -//--------------------------------------------------------------------------------------------------------------------- -inline auto LineMatrix(const VLayoutPiece &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos, - int maxLineWidth) -> QTransform -{ - QTransform labelMatrix; - labelMatrix.translate(topLeft.x(), topLeft.y()); - - if ((piece.IsVerticallyFlipped() && piece.IsHorizontallyFlipped()) || - (!piece.IsVerticallyFlipped() && !piece.IsHorizontallyFlipped())) - { - labelMatrix.rotate(-angle); - } - else if (piece.IsVerticallyFlipped() || piece.IsHorizontallyFlipped()) - { - if (piece.IsVerticallyFlipped()) - { - labelMatrix.scale(-1, 1); - labelMatrix.rotate(angle); - labelMatrix.translate(-maxLineWidth, 0); - } - - if (piece.IsHorizontallyFlipped()) - { - labelMatrix.scale(-1, 1); - labelMatrix.rotate(angle); - labelMatrix.translate(-maxLineWidth, 0); - } - } - - labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position - - labelMatrix *= piece.GetMatrix(); - - return labelMatrix; -} } // namespace //--------------------------------------------------------------------------------------------------------------------- @@ -1159,7 +1123,6 @@ void VDxfEngine::ExportPieceText(const QSharedPointer &detailBloc VTextManager const tm = detail.GetPieceLabelData(); const QVector labelLines = tm.GetLabelSourceLines(qFloor(dW), tm.GetFont()); - const int maxLineWidth = tm.MaxLineWidthOutlineFont(static_cast(dW)); for (const auto &tl : labelLines) { @@ -1174,7 +1137,7 @@ void VDxfEngine::ExportPieceText(const QSharedPointer &detailBloc dY += fm.height() * scale / 2; const qreal dX = LineAlign(tl, tl.m_qsText, fm, dW); - QTransform const lineMatrix = LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth); + QTransform const lineMatrix = detail.LineMatrix(labelShape.at(0), angle, QPointF(dX, dY), dW); QPointF const pos = lineMatrix.map(QPointF()); diff --git a/src/libs/vhpgl/vhpglengine.cpp b/src/libs/vhpgl/vhpglengine.cpp index e64000816..f0a538571 100644 --- a/src/libs/vhpgl/vhpglengine.cpp +++ b/src/libs/vhpgl/vhpglengine.cpp @@ -158,41 +158,6 @@ inline auto LineAlign(const TextLine &tl, const QString &text, const QFontMetric return dX; } -//--------------------------------------------------------------------------------------------------------------------- -auto LineMatrix(const VLayoutPiece &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos, - int maxLineWidth) -> QTransform -{ - QTransform labelMatrix; - labelMatrix.translate(topLeft.x(), topLeft.y()); - - if ((piece.IsVerticallyFlipped() && piece.IsHorizontallyFlipped()) || - (!piece.IsVerticallyFlipped() && !piece.IsHorizontallyFlipped())) - { - labelMatrix.rotate(angle); - } - else if (piece.IsVerticallyFlipped() || piece.IsHorizontallyFlipped()) - { - if (piece.IsVerticallyFlipped()) - { - labelMatrix.scale(-1, 1); - labelMatrix.rotate(-angle); - labelMatrix.translate(-maxLineWidth, 0); - } - - if (piece.IsHorizontallyFlipped()) - { - labelMatrix.scale(-1, 1); - labelMatrix.rotate(-angle); - labelMatrix.translate(-maxLineWidth, 0); - } - } - - labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position - labelMatrix *= piece.GetMatrix(); - - return labelMatrix; -} - //--------------------------------------------------------------------------------------------------------------------- auto OptimizePattern(QVector pattern) -> QVector { @@ -751,7 +716,6 @@ void VHPGLEngine::PlotLabelSVGFont(QTextStream &out, const VLayoutPiece &detail, const qreal dW = QLineF(labelShape.at(0), labelShape.at(1)).length(); const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length(); const qreal angle = -QLineF(labelShape.at(0), labelShape.at(1)).angle(); - const int maxLineWidth = tm.MaxLineWidthSVGFont(static_cast(dW), m_penWidthPx); qreal dY = m_penWidthPx; @@ -770,7 +734,7 @@ void VHPGLEngine::PlotLabelSVGFont(QTextStream &out, const VLayoutPiece &detail, const QString qsText = tl.m_qsText; const qreal dX = LineAlign(tl, qsText, engine, dW, m_penWidthPx); // set up the rotation around top-left corner matrix - const QTransform lineMatrix = LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth); + const QTransform lineMatrix = detail.LineMatrix(labelShape.at(0), angle, QPointF(dX, dY), dW); QPainterPath const path = lineMatrix.map(engine.DrawPath(QPointF(), qsText)); PlotPainterPath(out, path, Qt::SolidLine); @@ -791,7 +755,6 @@ void VHPGLEngine::PlotLabelOutlineFont(QTextStream &out, const VLayoutPiece &det const qreal dW = QLineF(labelShape.at(0), labelShape.at(1)).length(); const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length(); const qreal angle = -QLineF(labelShape.at(0), labelShape.at(1)).angle(); - const int maxLineWidth = tm.MaxLineWidthOutlineFont(static_cast(dW)); qreal dY = 0; @@ -824,7 +787,7 @@ void VHPGLEngine::PlotLabelOutlineFont(QTextStream &out, const VLayoutPiece &det const QString qsText = tl.m_qsText; const qreal dX = LineAlign(tl, qsText, fm, dW); // set up the rotation around top-left corner matrix - const QTransform lineMatrix = LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth); + const QTransform lineMatrix = detail.LineMatrix(labelShape.at(0), angle, QPointF(dX, dY), dW); QPainterPath path; diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp index 02a3b76f0..f3fab9f1f 100644 --- a/src/libs/vlayout/vlayoutpiece.cpp +++ b/src/libs/vlayout/vlayoutpiece.cpp @@ -1856,6 +1856,40 @@ auto VLayoutPiece::MapPassmark(VLayoutPassmark passmark, const QTransform &matri return passmark; } +//--------------------------------------------------------------------------------------------------------------------- +auto VLayoutPiece::LineMatrix(const QPointF &topLeft, qreal angle, const QPointF &linePos, qreal maxLineWidth) const + -> QTransform +{ + QTransform labelMatrix; + labelMatrix.translate(topLeft.x(), topLeft.y()); + + if ((IsVerticallyFlipped() && IsHorizontallyFlipped()) || (!IsVerticallyFlipped() && !IsHorizontallyFlipped())) + { + labelMatrix.rotate(angle); + } + else if (IsVerticallyFlipped() || IsHorizontallyFlipped()) + { + if (IsVerticallyFlipped() && !IsHorizontallyFlipped()) + { + labelMatrix.scale(-1, 1); + labelMatrix.rotate(-angle); + labelMatrix.translate(-maxLineWidth, 0); + } + + if (IsHorizontallyFlipped() && !IsVerticallyFlipped()) + { + labelMatrix.scale(-1, 1); + labelMatrix.rotate(-angle); + labelMatrix.translate(-maxLineWidth, 0); + } + } + + labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position + labelMatrix *= GetMatrix(); + + return labelMatrix; +} + //--------------------------------------------------------------------------------------------------------------------- auto VLayoutPiece::BoundingRect(QVector points) -> QRectF { @@ -2046,7 +2080,7 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector< { labelMatrix.scale(-1, 1); labelMatrix.rotate(-angle); - labelMatrix.translate(-tm.MaxLineWidthOutlineFont(static_cast(dW)), 0); + labelMatrix.translate(-qRound(dW), 0); } else { diff --git a/src/libs/vlayout/vlayoutpiece.h b/src/libs/vlayout/vlayoutpiece.h index f89fbcd37..f2f4a69c6 100644 --- a/src/libs/vlayout/vlayoutpiece.h +++ b/src/libs/vlayout/vlayoutpiece.h @@ -240,6 +240,9 @@ public: static auto MapPassmark(VLayoutPassmark passmark, const QTransform &matrix, bool mirror) -> VLayoutPassmark; + auto LineMatrix(const QPointF &topLeft, qreal angle, const QPointF &linePos, qreal maxLineWidth) const + -> QTransform; + protected: void SetGrainline(const VPieceGrainline &grainline); diff --git a/src/libs/vlayout/vtextmanager.cpp b/src/libs/vlayout/vtextmanager.cpp index 2d37eac08..e60aa3579 100644 --- a/src/libs/vlayout/vtextmanager.cpp +++ b/src/libs/vlayout/vtextmanager.cpp @@ -786,67 +786,6 @@ auto VTextManager::GetLabelSourceLines(int width, const VSvgFont &font, qreal pe return lines; } -//--------------------------------------------------------------------------------------------------------------------- -auto VTextManager::MaxLineWidthOutlineFont(int width) const -> int -{ - int maxWidth = 0; - for (int i = 0; i < m_liLines.count(); ++i) - { - const TextLine &tl = m_liLines.at(i); - - QFont fnt = m_font; - fnt.setPointSize(qMax(fnt.pointSize() + tl.m_iFontSize, 1)); - fnt.setBold(tl.m_bold); - fnt.setItalic(tl.m_italic); - - QFontMetrics const fm(fnt); - - QString qsText = tl.m_qsText; - - if (fm.horizontalAdvance(qsText) > width) - { - qsText = fm.elidedText(qsText, Qt::ElideMiddle, width); - } - - maxWidth = qMax(fm.horizontalAdvance(qsText), maxWidth); - } - - return maxWidth; -} - -//--------------------------------------------------------------------------------------------------------------------- -auto VTextManager::MaxLineWidthSVGFont(int width, qreal penWidth) const -> int -{ - VSvgFontDatabase *db = VAbstractApplication::VApp()->SVGFontDatabase(); - VSvgFontEngine engine = - db->FontEngine(m_svgFontFamily, SVGFontStyle::Normal, SVGFontWeight::Normal, m_svgFontPointSize); - VSvgFont const svgFont = engine.Font(); - - int maxWidth = 0; - for (int i = 0; i < m_liLines.count(); ++i) - { - const TextLine &tl = m_liLines.at(i); - - VSvgFont fnt = svgFont; - fnt.SetPointSize(fnt.PointSize() + tl.m_iFontSize); - fnt.SetBold(tl.m_bold); - fnt.SetItalic(tl.m_italic); - - engine = db->FontEngine(fnt); - - QString qsText = tl.m_qsText; - - if (engine.TextWidth(qsText, penWidth) > width) - { - qsText = engine.ElidedText(qsText, SVGTextElideMode::ElideMiddle, width); - } - - maxWidth = qMax(qRound(engine.TextWidth(qsText, penWidth)), maxWidth); - } - - return maxWidth; -} - //--------------------------------------------------------------------------------------------------------------------- /** * @brief VTextManager::Update updates the text lines with detail data diff --git a/src/libs/vlayout/vtextmanager.h b/src/libs/vlayout/vtextmanager.h index a09681aa6..3bddaaf75 100644 --- a/src/libs/vlayout/vtextmanager.h +++ b/src/libs/vlayout/vtextmanager.h @@ -104,9 +104,6 @@ public: auto GetLabelSourceLines(int width, const QFont &font) const -> QVector; auto GetLabelSourceLines(int width, const VSvgFont &font, qreal penWidth) const -> QVector; - auto MaxLineWidthOutlineFont(int width) const -> int; - auto MaxLineWidthSVGFont(int width, qreal penWidth) const -> int; - void Update(const QString &qsName, const VPieceLabelData &data, const VContainer *pattern); void Update(VAbstractPattern *pDoc, const VContainer *pattern);