Fix calculating label position for flipped piece.

This commit is contained in:
Roman Telezhynskyi 2024-04-12 09:51:49 +03:00
parent 55cc3a7d54
commit e4481754f0
7 changed files with 43 additions and 186 deletions

View File

@ -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<QPointF> &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<int>(dW), penWidth);
qreal dY = penWidth;
@ -467,7 +426,7 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &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<QPointF> &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<int>(dW));
qreal const penWidth = VPApplication::VApp()->PuzzleSettings()->GetLayoutLineWidth();
qreal dY = 0;
@ -533,7 +491,7 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector<QPointF> &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)
{

View File

@ -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<dx_ifaceBlock> &detailBloc
VTextManager const tm = detail.GetPieceLabelData();
const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), tm.GetFont());
const int maxLineWidth = tm.MaxLineWidthOutlineFont(static_cast<int>(dW));
for (const auto &tl : labelLines)
{
@ -1174,7 +1137,7 @@ void VDxfEngine::ExportPieceText(const QSharedPointer<dx_ifaceBlock> &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());

View File

@ -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<int> pattern) -> QVector<int>
{
@ -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<int>(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<int>(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;

View File

@ -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<QPointF> 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<int>(dW)), 0);
labelMatrix.translate(-qRound(dW), 0);
}
else
{

View File

@ -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);

View File

@ -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

View File

@ -104,9 +104,6 @@ public:
auto GetLabelSourceLines(int width, const QFont &font) const -> QVector<TextLine>;
auto GetLabelSourceLines(int width, const VSvgFont &font, qreal penWidth) const -> QVector<TextLine>;
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);