New features: Mirror line, Fold line.

This commit is contained in:
Roman Telezhynskyi 2024-01-06 14:20:56 +02:00
parent 670f08eb9b
commit 38fbc03f16
161 changed files with 30865 additions and 16436 deletions

View File

@ -60,6 +60,8 @@
- Optimize U-notch shape. - Optimize U-notch shape.
- New feature. Boundary together with notches. - New feature. Boundary together with notches.
- Puzzle app. Horizontal piece flipping. - Puzzle app. Horizontal piece flipping.
- Mirror line.
- Fold line.
# Valentina 0.7.52 September 12, 2022 # Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru. - Fix crash when default locale is ru.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -404,3 +404,15 @@ auto VPLayoutSettings::IsBoundaryTogetherWithNotches() const -> bool
{ {
return m_togetherWithNotches; return m_togetherWithNotches;
} }
//---------------------------------------------------------------------------------------------------------------------
void VPLayoutSettings::SetCutOnFold(bool value)
{
m_cutOnFold = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPLayoutSettings::IsCutOnFold() const -> bool
{
return m_cutOnFold;
}

View File

@ -322,6 +322,9 @@ public:
void SetBoundaryTogetherWithNotches(bool value); void SetBoundaryTogetherWithNotches(bool value);
auto IsBoundaryTogetherWithNotches() const -> bool; auto IsBoundaryTogetherWithNotches() const -> bool;
void SetCutOnFold(bool value);
auto IsCutOnFold() const -> bool;
private: private:
Unit m_unit{Unit::Cm}; Unit m_unit{Unit::Cm};
@ -382,6 +385,7 @@ private:
bool m_showTileNumbers{false}; bool m_showTileNumbers{false};
bool m_togetherWithNotches{false}; bool m_togetherWithNotches{false};
bool m_cutOnFold{false};
}; };
#endif // VPLAYOUTSETTINGS_H #endif // VPLAYOUTSETTINGS_H

View File

@ -32,12 +32,12 @@
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
#include "qline.h" #include "../vwidgets/vpiecegrainline.h"
#include "vpiecegrainline.h"
#include "vplayout.h" #include "vplayout.h"
#include "vpsheet.h" #include "vpsheet.h"
#include <QIcon> #include <QIcon>
#include <QLine>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
@ -123,7 +123,7 @@ auto ClosestDistance(const QVector<QPointF> &path1, const QVector<QPointF> &path
{ {
for (auto p2 : path2) for (auto p2 : path2)
{ {
QLineF d(p1, p2); QLineF const d(p1, p2);
if (d.length() <= distance) if (d.length() <= distance)
{ {
distance = d.length(); distance = d.length();
@ -141,11 +141,6 @@ VPPiece::VPPiece(const VLayoutPiece &layoutPiece)
: VLayoutPiece(layoutPiece) : VLayoutPiece(layoutPiece)
{ {
ClearTransformations(); ClearTransformations();
if (IsForceFlipping())
{
FlipVertically();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -167,6 +162,18 @@ void VPPiece::Update(const VPPiecePtr &piece)
SetPieceLabelData(piece->GetPieceLabelData()); SetPieceLabelData(piece->GetPieceLabelData());
SetPatternLabelRect(piece->GetPatternLabelRect()); SetPatternLabelRect(piece->GetPatternLabelRect());
SetPatternLabelData(piece->GetPatternLabelData()); SetPatternLabelData(piece->GetPatternLabelData());
SetSeamMirrorLine(piece->GetSeamMirrorLine());
SetSeamAllowanceMirrorLine(piece->GetMappedSeamAllowanceMirrorLine());
SetFoldLineLabel(piece->GetFoldLineLabel());
SetFoldLineLabelAlignment(piece->GetFoldLineLabelAlignment());
SetFoldLineType(piece->GetFoldLineType());
SetFoldLineSvgFontSize(piece->GetFoldLineSvgFontSize());
SetFoldLineLabelFontItalic(piece->IsFoldLineLabelFontItalic());
SetFoldLineLabelFontBold(piece->IsFoldLineLabelFontBold());
SetFoldLineOutlineFont(piece->GetFoldLineOutlineFont());
SetFoldLineSVGFontFamily(piece->GetFoldLineSVGFontFamily());
SetFoldLineHeight(piece->GetFoldLineHeight());
SetFoldLineWidth(piece->GetFoldLineWidth());
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -202,6 +209,11 @@ void VPPiece::ClearTransformations()
SetVerticallyFlipped(false); SetVerticallyFlipped(false);
SetHorizontallyFlipped(false); SetHorizontallyFlipped(false);
if (IsForceFlipping())
{
FlipVertically();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -291,7 +303,7 @@ void VPPiece::SetGrainline(const VPieceGrainline &grainline)
void VPPiece::FlipVertically() void VPPiece::FlipVertically()
{ {
QTransform pieceMatrix = GetMatrix(); QTransform pieceMatrix = GetMatrix();
QPointF center = pieceMatrix.map(DetailBoundingRect().center()); QPointF const center = pieceMatrix.map(DetailBoundingRect().center());
QTransform m; QTransform m;
m.translate(center.x(), 0); m.translate(center.x(), 0);
@ -307,7 +319,7 @@ void VPPiece::FlipVertically()
void VPPiece::FlipHorizontally() void VPPiece::FlipHorizontally()
{ {
QTransform pieceMatrix = GetMatrix(); QTransform pieceMatrix = GetMatrix();
QPointF center = pieceMatrix.map(DetailBoundingRect().center()); QPointF const center = pieceMatrix.map(DetailBoundingRect().center());
QTransform m; QTransform m;
m.translate(0, center.y()); m.translate(0, center.y());
@ -322,85 +334,52 @@ void VPPiece::FlipHorizontally()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPPiece::StickyPosition(qreal &dx, qreal &dy) const -> bool auto VPPiece::StickyPosition(qreal &dx, qreal &dy) const -> bool
{ {
VPLayoutPtr layout = Layout(); VPLayoutPtr const layout = Layout();
if (layout.isNull() || not layout->LayoutSettings().GetStickyEdges()) if (layout.isNull() || not layout->LayoutSettings().GetStickyEdges())
{ {
return false; return false;
} }
const qreal pieceGap = layout->LayoutSettings().GetPiecesGap(); VPSheetPtr const sheet = Sheet();
if (pieceGap <= 0)
{
return false;
}
VPSheetPtr sheet = Sheet();
if (sheet.isNull()) if (sheet.isNull())
{ {
return false; return false;
} }
QList<VPPiecePtr> allPieces = sheet->GetPieces(); VStickyDistance match;
if (allPieces.count() < 2) if (!StickySheet(match))
{ {
return false; return false;
} }
QVector<QPointF> path; if (!StickyPieces(match))
CastTo(GetMappedExternalContourPoints(), path);
QRectF boundingRect = VLayoutPiece::BoundingRect(path);
const qreal stickyDistance = pieceGap + minStickyDistance;
QRectF stickyZone = QRectF(boundingRect.topLeft().x() - stickyDistance, boundingRect.topLeft().y() - stickyDistance,
boundingRect.width() + stickyDistance * 2, boundingRect.height() + stickyDistance * 2);
QVector<QPointF> stickyPath = PrepareStickyPath(path);
QLineF closestDistance;
for (const auto &piece : allPieces)
{
if (piece.isNull() || piece->GetUniqueID() == GetUniqueID())
{
continue;
}
QVector<QPointF> piecePath;
CastTo(piece->GetMappedExternalContourPoints(), piecePath);
QRectF pieceBoundingRect = VLayoutPiece::BoundingRect(piecePath);
if (stickyZone.intersects(pieceBoundingRect) || pieceBoundingRect.contains(stickyZone) ||
stickyZone.contains(pieceBoundingRect))
{
if (not VPPiece::PathsSuperposition(path, piecePath))
{
QVector<QPointF> pieceStickyPath = PrepareStickyPath(piecePath);
closestDistance = ClosestDistance(stickyPath, pieceStickyPath);
}
}
}
if (closestDistance.isNull())
{ {
return false; return false;
} }
const qreal extraZone = qBound(minStickyDistance, pieceGap * 50 / 100, maxStickyDistance); if (match.m_closestDistance.isNull())
const qreal length = closestDistance.length();
if (length > pieceGap && length <= pieceGap + extraZone)
{ {
closestDistance.setLength(length - pieceGap); return false;
QPointF diff = closestDistance.p2() - closestDistance.p1(); }
const qreal extraZone = qBound(minStickyDistance, match.m_pieceGap * 50 / 100, maxStickyDistance);
const qreal length = match.m_closestDistance.length();
if (length > match.m_pieceGap && length <= match.m_pieceGap + extraZone)
{
match.m_closestDistance.setLength(length - match.m_pieceGap);
QPointF const diff = match.m_closestDistance.p2() - match.m_closestDistance.p1();
dx = diff.x(); dx = diff.x();
dy = diff.y(); dy = diff.y();
return true; return true;
} }
if (length < pieceGap && length >= pieceGap - extraZone) if (length < match.m_pieceGap && length >= match.m_pieceGap - extraZone)
{ {
closestDistance.setAngle(closestDistance.angle() + 180); match.m_closestDistance.setAngle(match.m_closestDistance.angle() + 180);
closestDistance.setLength(pieceGap - length); match.m_closestDistance.setLength(match.m_pieceGap - length);
QPointF diff = closestDistance.p2() - closestDistance.p1(); QPointF const diff = match.m_closestDistance.p2() - match.m_closestDistance.p1();
dx = diff.x(); dx = diff.x();
dy = diff.y(); dy = diff.y();
return true; return true;
@ -471,6 +450,179 @@ void VPPiece::SetCopyNumber(quint16 newCopyNumber)
m_copyNumber = qMax(static_cast<quint16>(1), newCopyNumber); m_copyNumber = qMax(static_cast<quint16>(1), newCopyNumber);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VPPiece::StickySheet(VStickyDistance &match) const -> bool
{
VPLayoutPtr const layout = Layout();
if (layout.isNull())
{
return false;
}
const qreal pieceGap = layout->LayoutSettings().GetPiecesGap();
if (pieceGap <= 0)
{
return false;
}
VPSheetPtr const sheet = Sheet();
if (sheet.isNull())
{
return false;
}
QRectF sheetRect = sheet->GetMarginsRect();
QVector<QPointF> path;
CastTo(GetMappedExternalContourPoints(), path);
QRectF const boundingRect = VLayoutPiece::BoundingRect(path);
if (!sheetRect.contains(boundingRect))
{
return true;
}
const qreal stickyDistance = maxStickyDistance;
QRectF const stickyZone =
QRectF(boundingRect.topLeft().x() - stickyDistance, boundingRect.topLeft().y() - stickyDistance,
boundingRect.width() + stickyDistance * 2, boundingRect.height() + stickyDistance * 2);
if (!stickyZone.intersects(sheetRect))
{
return true;
}
QVector<QPointF> const stickyPath = PrepareStickyPath(path);
if (!layout->LayoutSettings().IsCutOnFold())
{
sheetRect.adjust(accuracyPointOnLine, accuracyPointOnLine, -accuracyPointOnLine, -accuracyPointOnLine);
QVector<QPointF> const sheetPath{sheetRect.topLeft(), sheetRect.topRight(), sheetRect.bottomRight(),
sheetRect.bottomLeft(), sheetRect.topLeft()};
QVector<QPointF> const sheetStickyPath = PrepareStickyPath(sheetPath);
QLineF const distance = ClosestDistance(stickyPath, sheetStickyPath);
if (match.m_closestDistance.isNull() || distance.length() < match.m_closestDistance.length())
{
match.m_closestDistance = distance;
}
return true;
}
if (GetSeamAllowanceMirrorLine().isNull() || (!GetSeamAllowanceMirrorLine().isNull() && IsShowFullPiece()))
{ // regular piece
QVector<QPointF> sheetPath;
if (sheetRect.width() >= sheetRect.height())
{
sheetRect.adjust(accuracyPointOnLine, accuracyPointOnLine, -accuracyPointOnLine, -accuracyPointOnLine);
QPointF const shift(0, pieceGap / 2. - accuracyPointOnLine);
sheetPath = {sheetRect.topLeft() + shift, sheetRect.topRight() + shift, sheetRect.bottomRight(),
sheetRect.bottomLeft(), sheetRect.topLeft() + shift};
}
else
{
sheetRect.adjust(accuracyPointOnLine, accuracyPointOnLine, -accuracyPointOnLine, -accuracyPointOnLine);
QPointF const shift(pieceGap / 2. - accuracyPointOnLine, 0);
sheetPath = {sheetRect.topLeft(), sheetRect.topRight() - shift, sheetRect.bottomRight() - shift,
sheetRect.bottomLeft(), sheetRect.topLeft()};
}
QVector<QPointF> const sheetStickyPath = PrepareStickyPath(sheetPath);
QLineF const distance = ClosestDistance(stickyPath, sheetStickyPath);
if (match.m_closestDistance.isNull() || distance.length() < match.m_closestDistance.length())
{
match.m_closestDistance = distance;
}
return true;
}
// mirrored piece
QVector<QPointF> sheetPath;
if (sheetRect.width() >= sheetRect.height())
{
QPointF const shift(0, accuracyPointOnLine);
sheetPath = {sheetRect.topLeft() + shift, sheetRect.topRight() + shift};
}
else
{
QPointF const shift(accuracyPointOnLine, 0);
sheetPath = {sheetRect.topRight() - shift, sheetRect.bottomRight() - shift};
}
QVector<QPointF> const sheetStickyPath = PrepareStickyPath(sheetPath);
QLineF const distance = ClosestDistance(stickyPath, sheetStickyPath);
if (match.m_closestDistance.isNull() || distance.length() < match.m_closestDistance.length())
{
match.m_closestDistance = distance;
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPPiece::StickyPieces(VStickyDistance &match) const -> bool
{
VPLayoutPtr const layout = Layout();
if (layout.isNull())
{
return false;
}
const qreal pieceGap = layout->LayoutSettings().GetPiecesGap();
if (pieceGap <= 0)
{
return false;
}
VPSheetPtr const sheet = Sheet();
if (sheet.isNull())
{
return false;
}
QList<VPPiecePtr> const allPieces = sheet->GetPieces();
if (allPieces.count() < 2)
{
return true;
}
QVector<QPointF> path;
CastTo(GetMappedExternalContourPoints(), path);
QRectF const boundingRect = VLayoutPiece::BoundingRect(path);
const qreal stickyDistance = pieceGap + minStickyDistance;
QRectF const stickyZone =
QRectF(boundingRect.topLeft().x() - stickyDistance, boundingRect.topLeft().y() - stickyDistance,
boundingRect.width() + stickyDistance * 2, boundingRect.height() + stickyDistance * 2);
QVector<QPointF> const stickyPath = PrepareStickyPath(path);
for (const auto &piece : allPieces)
{
if (piece.isNull() || piece->GetUniqueID() == GetUniqueID())
{
continue;
}
QVector<QPointF> piecePath;
CastTo(piece->GetMappedExternalContourPoints(), piecePath);
QRectF const pieceBoundingRect = VLayoutPiece::BoundingRect(piecePath);
if (stickyZone.intersects(pieceBoundingRect) || pieceBoundingRect.contains(stickyZone) ||
stickyZone.contains(pieceBoundingRect))
{
if (not VPPiece::PathsSuperposition(path, piecePath))
{
QVector<QPointF> const pieceStickyPath = PrepareStickyPath(piecePath);
QLineF const distance = ClosestDistance(stickyPath, pieceStickyPath);
if (match.m_closestDistance.isNull() || distance.length() < match.m_closestDistance.length())
{
match.m_closestDistance = distance;
match.m_pieceGap = pieceGap;
}
}
}
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPPiece::CleanPosition(const VPPiecePtr &piece) void VPPiece::CleanPosition(const VPPiecePtr &piece)
{ {
@ -530,4 +682,6 @@ void VPPiece::CleanPosition(const VPPiecePtr &piece)
piece->SetPieceLabelRect(MapVector(piece->GetPieceLabelRect(), matrix)); piece->SetPieceLabelRect(MapVector(piece->GetPieceLabelRect(), matrix));
piece->SetPatternLabelRect(MapVector(piece->GetPatternLabelRect(), matrix)); piece->SetPatternLabelRect(MapVector(piece->GetPatternLabelRect(), matrix));
piece->SetSeamMirrorLine(matrix.map(piece->GetSeamMirrorLine()));
piece->SetSeamAllowanceMirrorLine(matrix.map(piece->GetSeamAllowanceMirrorLine()));
} }

View File

@ -44,6 +44,12 @@
class VPLayout; class VPLayout;
class VPSheet; class VPSheet;
struct VStickyDistance
{
QLineF m_closestDistance{};
qreal m_pieceGap{0};
};
class VPPiece : public VLayoutPiece class VPPiece : public VLayoutPiece
{ {
Q_DECLARE_TR_FUNCTIONS(VPPiece) // NOLINT Q_DECLARE_TR_FUNCTIONS(VPPiece) // NOLINT
@ -136,6 +142,9 @@ private:
quint16 m_copyNumber{1}; quint16 m_copyNumber{1};
qreal m_zValue{1.0}; qreal m_zValue{1.0};
auto StickySheet(VStickyDistance &match) const -> bool;
auto StickyPieces(VStickyDistance &match) const -> bool;
}; };
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -143,7 +143,7 @@ void VPSheetSceneData::PrepareForExport()
m_rotationControls->setVisible(false); m_rotationControls->setVisible(false);
m_rotationOrigin->setVisible(false); m_rotationOrigin->setVisible(false);
VPLayoutPtr layout = m_layout.toStrongRef(); VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull()) if (not layout.isNull())
{ {
m_showGridTmp = layout->LayoutSettings().GetShowGrid(); m_showGridTmp = layout->LayoutSettings().GetShowGrid();
@ -152,7 +152,7 @@ void VPSheetSceneData::PrepareForExport()
m_showTilesTmp = layout->LayoutSettings().GetShowTiles(); m_showTilesTmp = layout->LayoutSettings().GetShowTiles();
layout->LayoutSettings().SetShowTiles(false); layout->LayoutSettings().SetShowTiles(false);
VPSheetPtr sheet = layout->GetSheet(m_sheetUuid); VPSheetPtr const sheet = layout->GetSheet(m_sheetUuid);
m_slectedPiecesTmp = sheet->GetSelectedPieces(); m_slectedPiecesTmp = sheet->GetSelectedPieces();
for (const auto &piece : qAsConst(m_slectedPiecesTmp)) for (const auto &piece : qAsConst(m_slectedPiecesTmp))
@ -185,7 +185,7 @@ void VPSheetSceneData::CleanAfterExport()
m_rotationControls->setVisible(true); m_rotationControls->setVisible(true);
VPLayoutPtr layout = m_layout.toStrongRef(); VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull()) if (not layout.isNull())
{ {
layout->LayoutSettings().SetShowGrid(m_showGridTmp); layout->LayoutSettings().SetShowGrid(m_showGridTmp);
@ -544,7 +544,7 @@ void VPSheet::ValidateSuperpositionOfPieces() const
QVector<QPointF> path2; QVector<QPointF> path2;
CastTo(p->GetMappedExternalContourPoints(), path2); CastTo(p->GetMappedExternalContourPoints(), path2);
bool superposition = VPPiece::PathsSuperposition(path1, path2); bool const superposition = VPPiece::PathsSuperposition(path1, path2);
if (superposition) if (superposition)
{ {
hasSuperposition = superposition; hasSuperposition = superposition;
@ -556,7 +556,7 @@ void VPSheet::ValidateSuperpositionOfPieces() const
if (oldSuperpositionOfPieces != piece->HasSuperpositionWithPieces()) if (oldSuperpositionOfPieces != piece->HasSuperpositionWithPieces())
{ {
VPLayoutPtr layout = GetLayout(); VPLayoutPtr const layout = GetLayout();
if (not layout.isNull()) if (not layout.isNull())
{ {
emit layout->PiecePositionValidityChanged(piece); emit layout->PiecePositionValidityChanged(piece);
@ -574,15 +574,26 @@ void VPSheet::ValidatePieceOutOfBound(const VPPiecePtr &piece) const
} }
const bool oldOutOfBound = piece->OutOfBound(); const bool oldOutOfBound = piece->OutOfBound();
QRectF const sheetRect = GetMarginsRect();
QRectF pieceRect = piece->MappedDetailBoundingRect(); VPLayoutPtr const layout = GetLayout();
QRectF sheetRect = GetMarginsRect(); if (not layout.isNull() && layout->LayoutSettings().IsCutOnFold() && not piece->IsShowFullPiece() &&
!piece->GetSeamMirrorLine().isNull())
piece->SetOutOfBound(not sheetRect.contains(pieceRect)); {
QLineF const foldLine = sheetRect.width() >= sheetRect.height()
? QLineF(sheetRect.topLeft(), sheetRect.topRight())
: QLineF(sheetRect.topRight(), sheetRect.bottomRight());
piece->SetOutOfBound(not VGObject::IsLineSegmentOnLineSegment(
foldLine, piece->GetMappedSeamAllowanceMirrorLine(), MmToPixel(0.5)));
}
else
{
QRectF const pieceRect = piece->MappedDetailBoundingRect();
piece->SetOutOfBound(not sheetRect.contains(pieceRect));
}
if (oldOutOfBound != piece->OutOfBound()) if (oldOutOfBound != piece->OutOfBound())
{ {
VPLayoutPtr layout = GetLayout();
if (not layout.isNull()) if (not layout.isNull())
{ {
emit layout->PiecePositionValidityChanged(piece); emit layout->PiecePositionValidityChanged(piece);
@ -593,7 +604,7 @@ void VPSheet::ValidatePieceOutOfBound(const VPPiecePtr &piece) const
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPSheet::ValidatePiecesOutOfBound() const void VPSheet::ValidatePiecesOutOfBound() const
{ {
QList<VPPiecePtr> pieces = GetPieces(); QList<VPPiecePtr> const pieces = GetPieces();
for (const auto &piece : pieces) for (const auto &piece : pieces)
{ {
ValidatePieceOutOfBound(piece); ValidatePieceOutOfBound(piece);

View File

@ -28,6 +28,8 @@
#ifndef SCENEDEF_H #ifndef SCENEDEF_H
#define SCENEDEF_H #define SCENEDEF_H
#include "qtypes.h"
enum class PGraphicsItem : int enum class PGraphicsItem : int
{ {
Piece = 1, Piece = 1,
@ -35,4 +37,7 @@ enum class PGraphicsItem : int
TransformationOrigin = 3 TransformationOrigin = 3
}; };
constexpr qreal foldTextMargin = 5;
constexpr int foldFontSize = 34;
#endif // SCENEDEF_H #endif // SCENEDEF_H

View File

@ -45,6 +45,7 @@
#include "../vformat/vsinglelineoutlinechar.h" #include "../vformat/vsinglelineoutlinechar.h"
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vlayout/vboundary.h" #include "../vlayout/vboundary.h"
#include "../vlayout/vfoldline.h"
#include "../vlayout/vgraphicsfillitem.h" #include "../vlayout/vgraphicsfillitem.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
@ -53,7 +54,9 @@
#include "../vmisc/svgfont/vsvgfontengine.h" #include "../vmisc/svgfont/vsvgfontengine.h"
#include "../vmisc/theme/vscenestylesheet.h" #include "../vmisc/theme/vscenestylesheet.h"
#include "../vpapplication.h" #include "../vpapplication.h"
#include "../vpatterndb/vpiecepath.h"
#include "compatibility.h" #include "compatibility.h"
#include "qtpreprocessorsupport.h"
#include "undocommands/vpundomovepieceonsheet.h" #include "undocommands/vpundomovepieceonsheet.h"
#include "undocommands/vpundopiecemove.h" #include "undocommands/vpundopiecemove.h"
#include "vpiecegrainline.h" #include "vpiecegrainline.h"
@ -72,7 +75,7 @@ namespace
{ {
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline auto LineMatrix(const VPPiecePtr &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos, inline auto LineMatrix(const VPPiecePtr &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos,
int maxLineWidth, qreal maxLabelHeight) -> QTransform int maxLineWidth) -> QTransform
{ {
if (piece.isNull()) if (piece.isNull())
{ {
@ -82,26 +85,27 @@ inline auto LineMatrix(const VPPiecePtr &piece, const QPointF &topLeft, qreal an
QTransform labelMatrix; QTransform labelMatrix;
labelMatrix.translate(topLeft.x(), topLeft.y()); labelMatrix.translate(topLeft.x(), topLeft.y());
if (piece->IsVerticallyFlipped() || piece->IsHorizontallyFlipped()) if ((piece->IsVerticallyFlipped() && piece->IsHorizontallyFlipped()) ||
(!piece->IsVerticallyFlipped() && !piece->IsHorizontallyFlipped()))
{ {
if (piece->IsVerticallyFlipped()) labelMatrix.rotate(angle);
}
else if (piece->IsVerticallyFlipped() || piece->IsHorizontallyFlipped())
{
if (piece->IsVerticallyFlipped() && !piece->IsHorizontallyFlipped())
{ {
labelMatrix.scale(-1, 1); labelMatrix.scale(-1, 1);
labelMatrix.rotate(-angle); labelMatrix.rotate(-angle);
labelMatrix.translate(-maxLineWidth, 0); labelMatrix.translate(-maxLineWidth, 0);
} }
if (piece->IsHorizontallyFlipped()) if (piece->IsHorizontallyFlipped() && !piece->IsVerticallyFlipped())
{ {
labelMatrix.scale(1, -1); labelMatrix.scale(-1, 1);
labelMatrix.rotate(-angle); labelMatrix.rotate(-angle);
labelMatrix.translate(0, -maxLabelHeight); labelMatrix.translate(-maxLineWidth, 0);
} }
} }
else
{
labelMatrix.rotate(angle);
}
labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position
labelMatrix *= piece->GetMatrix(); labelMatrix *= piece->GetMatrix();
@ -177,73 +181,7 @@ inline auto LineAlign(const TextLine &tl, const QString &text, const VSvgFontEng
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
inline auto SelectionBrush() -> QBrush inline auto SelectionBrush() -> QBrush
{ {
return {QColor(255, 160, 160, 60)}; return {VSceneStylesheet::ManualLayoutStyle().PieceSelectionBrushColor()};
}
//---------------------------------------------------------------------------------------------------------------------
auto LabelHeightSVGFont(const VPPiecePtr &piece, const QVector<TextLine> &labelLines, const VSvgFont &svgFont,
const VSvgFontDatabase *db, qreal penWidth, qreal dH, int spacing) -> qreal
{
qreal labelHeight = 0;
if (piece->IsHorizontallyFlipped())
{
for (int i = 0; i < labelLines.size(); ++i)
{
const VSvgFont fnt = LineFont(labelLines.at(i), svgFont);
VSvgFontEngine engine = db->FontEngine(fnt);
const qreal lineHeight = engine.FontHeight() + penWidth;
if (labelHeight + lineHeight > dH)
{
break;
}
if (i < labelLines.size() - 1)
{
labelHeight += lineHeight + spacing;
}
else
{
labelHeight += lineHeight;
}
}
}
return labelHeight;
}
//---------------------------------------------------------------------------------------------------------------------
auto LabelHeightOutlineFont(const VPPiecePtr &piece, const QVector<TextLine> &labelLines, const QFont &font,
bool textAsPaths, qreal penWidth, qreal dH, int spacing) -> qreal
{
qreal labelHeight = 0;
if (piece->IsHorizontallyFlipped())
{
for (int i = 0; i < labelLines.size(); ++i)
{
const QFont fnt = LineFont(labelLines.at(i), font);
QFontMetrics fm(fnt);
const qreal lineHeight = textAsPaths ? fm.height() + penWidth : fm.height();
if (labelHeight + lineHeight > dH)
{
break;
}
if (i < labelLines.size() - 1)
{
labelHeight += lineHeight + spacing;
}
else
{
labelHeight += lineHeight;
}
}
}
return labelHeight;
} }
} // namespace } // namespace
@ -283,6 +221,8 @@ auto VPGraphicsPiece::boundingRect() const -> QRectF
shape.addPath(m_passmarks); shape.addPath(m_passmarks);
shape.addPath(m_placeLabels); shape.addPath(m_placeLabels);
shape.addPath(m_stickyPath); shape.addPath(m_stickyPath);
shape.addPath(m_foldLineMarkPath);
shape.addPath(m_foldLineLabelPath);
VPSettings *settings = VPApplication::VApp()->PuzzleSettings(); VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
const qreal halfPenWidth = settings->GetLayoutLineWidth() / 2.; const qreal halfPenWidth = settings->GetLayoutLineWidth() / 2.;
@ -308,7 +248,7 @@ void VPGraphicsPiece::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
Q_UNUSED(option); Q_UNUSED(option);
VPSettings *settings = VPApplication::VApp()->PuzzleSettings(); VPSettings *settings = VPApplication::VApp()->PuzzleSettings();
QPen pen(PieceColor(), settings->GetLayoutLineWidth(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); QPen const pen(PieceColor(), settings->GetLayoutLineWidth(), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
painter->setPen(pen); painter->setPen(pen);
PaintPiece(painter); PaintPiece(painter);
@ -459,7 +399,7 @@ void VPGraphicsPiece::InitLabels()
m_labelPathItems.clear(); m_labelPathItems.clear();
m_labelTextItems.clear(); m_labelTextItems.clear();
VPPiecePtr piece = m_piece.toStrongRef(); VPPiecePtr const piece = m_piece.toStrongRef();
if (piece.isNull()) if (piece.isNull())
{ {
return; return;
@ -481,7 +421,7 @@ void VPGraphicsPiece::SetStickyPoints(const QVector<QPointF> &newStickyPoint)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &labelShape, const VTextManager &tm) void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &labelShape, const VTextManager &tm)
{ {
VPPiecePtr piece = m_piece.toStrongRef(); VPPiecePtr const piece = m_piece.toStrongRef();
if (piece.isNull()) if (piece.isNull())
{ {
return; return;
@ -496,16 +436,16 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &labelShape,
VSvgFontEngine engine = VSvgFontEngine engine =
db->FontEngine(tm.GetSVGFontFamily(), SVGFontStyle::Normal, SVGFontWeight::Normal, tm.GetSVGFontPointSize()); db->FontEngine(tm.GetSVGFontFamily(), SVGFontStyle::Normal, SVGFontWeight::Normal, tm.GetSVGFontPointSize());
VSvgFont svgFont = engine.Font(); VSvgFont const svgFont = engine.Font();
if (!svgFont.IsValid()) if (!svgFont.IsValid())
{ {
QString errorMsg = QStringLiteral("Invalid SVG font '%1'. Fallback to outline font.").arg(svgFont.Name()); QString const errorMsg = QStringLiteral("Invalid SVG font '%1'. Fallback to outline font.").arg(svgFont.Name());
qDebug() << errorMsg; qDebug() << errorMsg;
InitPieceLabelOutlineFont(labelShape, tm); InitPieceLabelOutlineFont(labelShape, tm);
return; return;
} }
qreal penWidth = VPApplication::VApp()->PuzzleSettings()->GetLayoutLineWidth(); qreal const penWidth = VPApplication::VApp()->PuzzleSettings()->GetLayoutLineWidth();
const qreal dW = QLineF(labelShape.at(0), labelShape.at(1)).length(); const qreal dW = QLineF(labelShape.at(0), labelShape.at(1)).length();
const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length(); const qreal dH = QLineF(labelShape.at(1), labelShape.at(2)).length();
@ -517,8 +457,6 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &labelShape,
const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), svgFont, penWidth); const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), svgFont, penWidth);
const qreal labelHeight = LabelHeightSVGFont(piece, labelLines, svgFont, db, penWidth, dH, tm.GetSpacing());
for (const auto &tl : labelLines) for (const auto &tl : labelLines)
{ {
const VSvgFont fnt = LineFont(tl, svgFont); const VSvgFont fnt = LineFont(tl, svgFont);
@ -532,8 +470,7 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &labelShape,
const QString qsText = tl.m_qsText; const QString qsText = tl.m_qsText;
const qreal dX = LineAlign(tl, qsText, engine, dW, penWidth); const qreal dX = LineAlign(tl, qsText, engine, dW, penWidth);
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
const QTransform lineMatrix = const QTransform lineMatrix = LineMatrix(piece, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth);
LineMatrix(piece, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth, labelHeight);
auto *item = new QGraphicsPathItem(this); auto *item = new QGraphicsPathItem(this);
item->setPath(engine.DrawPath(QPointF(), qsText)); item->setPath(engine.DrawPath(QPointF(), qsText));
@ -549,7 +486,7 @@ void VPGraphicsPiece::InitPieceLabelSVGFont(const QVector<QPointF> &labelShape,
item->setTransform(lineMatrix); item->setTransform(lineMatrix);
m_labelPathItems.append(item); m_labelPathItems.append(item);
dY += engine.FontHeight() + penWidth + tm.GetSpacing(); dY += engine.FontHeight() - penWidth * 2 + tm.GetSpacing();
} }
} }
@ -587,31 +524,19 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector<QPointF> &labelSha
const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), tm.GetFont()); const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), tm.GetFont());
const qreal labelHeight =
LabelHeightOutlineFont(piece, labelLines, tm.GetFont(), textAsPaths, penWidth, dH, tm.GetSpacing());
for (const auto &tl : labelLines) for (const auto &tl : labelLines)
{ {
const QFont fnt = LineFont(tl, tm.GetFont()); const QFont fnt = LineFont(tl, tm.GetFont());
QFontMetrics const fm(fnt);
VSingleLineOutlineChar corrector(fnt);
if (settings->GetSingleStrokeOutlineFont() && !corrector.IsPopulated())
{
corrector.LoadCorrections(settings->GetPathFontCorrections());
}
QFontMetrics fm(fnt);
if (dY + fm.height() > dH) if (dY + fm.height() > dH)
{ {
break; break;
} }
const QString qsText = tl.m_qsText; const qreal dX = LineAlign(tl, tl.m_qsText, fm, dW);
const qreal dX = LineAlign(tl, qsText, fm, dW);
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
const QTransform lineMatrix = const QTransform lineMatrix = LineMatrix(piece, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth);
LineMatrix(piece, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth, labelHeight);
if (textAsPaths) if (textAsPaths)
{ {
@ -619,8 +544,14 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector<QPointF> &labelSha
if (settings->GetSingleStrokeOutlineFont()) if (settings->GetSingleStrokeOutlineFont())
{ {
VSingleLineOutlineChar const corrector(fnt);
if (!corrector.IsPopulated())
{
corrector.LoadCorrections(settings->GetPathFontCorrections());
}
int w = 0; int w = 0;
for (auto c : qAsConst(qsText)) for (auto c : qAsConst(tl.m_qsText))
{ {
path.addPath(corrector.DrawChar(w, static_cast<qreal>(fm.ascent()), c)); path.addPath(corrector.DrawChar(w, static_cast<qreal>(fm.ascent()), c));
w += TextWidth(fm, c); w += TextWidth(fm, c);
@ -628,7 +559,7 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector<QPointF> &labelSha
} }
else else
{ {
path.addText(0, static_cast<qreal>(fm.ascent()), fnt, qsText); path.addText(0, static_cast<qreal>(fm.ascent()), fnt, tl.m_qsText);
} }
auto *item = new QGraphicsPathItem(this); auto *item = new QGraphicsPathItem(this);
@ -644,18 +575,18 @@ void VPGraphicsPiece::InitPieceLabelOutlineFont(const QVector<QPointF> &labelSha
item->setTransform(lineMatrix); item->setTransform(lineMatrix);
m_labelPathItems.append(item); m_labelPathItems.append(item);
dY += fm.height() + penWidth + tm.GetSpacing(); dY += fm.height() + penWidth + MmToPixel(1.5) + tm.GetSpacing();
} }
else else
{ {
auto *item = new QGraphicsSimpleTextItem(this); auto *item = new QGraphicsSimpleTextItem(this);
item->setFont(fnt); item->setFont(fnt);
item->setText(qsText); item->setText(tl.m_qsText);
item->setBrush(QBrush(color)); item->setBrush(QBrush(color));
item->setTransform(lineMatrix); item->setTransform(lineMatrix);
m_labelTextItems.append(item); m_labelTextItems.append(item);
dY += (fm.height() + tm.GetSpacing()); dY += (fm.height() + MmToPixel(1.5) + tm.GetSpacing());
} }
} }
} }
@ -706,8 +637,10 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
m_passmarks = QPainterPath(); m_passmarks = QPainterPath();
m_placeLabels = QPainterPath(); m_placeLabels = QPainterPath();
m_stickyPath = QPainterPath(); m_stickyPath = QPainterPath();
m_foldLineMarkPath = QPainterPath();
m_foldLineLabelPath = QPainterPath();
VPPiecePtr piece = m_piece.toStrongRef(); VPPiecePtr const piece = m_piece.toStrongRef();
if (piece.isNull()) if (piece.isNull())
{ {
return; return;
@ -728,66 +661,76 @@ void VPGraphicsPiece::PaintPiece(QPainter *painter)
// initialises the place labels (buttons etc) // initialises the place labels (buttons etc)
PaintPlaceLabels(painter, piece); PaintPlaceLabels(painter, piece);
PaintMirrorLine(painter, piece);
PaintFoldLine(painter, piece);
PaintStickyPath(painter); PaintStickyPath(painter);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintSeamLine(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintSeamLine(QPainter *painter, const VPPiecePtr &piece)
{ {
if (piece->IsSeamAllowance() && not piece->IsHideMainPath() && not piece->IsSeamAllowanceBuiltIn()) if (piece->IsHideMainPath() && piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn())
{ {
QVector<VLayoutPoint> seamLinePoints = piece->GetMappedContourPoints(); return;
}
if (seamLinePoints.isEmpty()) QVector<VLayoutPoint> const seamLinePoints = piece->GetMappedFullContourPoints();
if (seamLinePoints.isEmpty())
{
return;
}
VPLayoutPtr const layout = piece->Layout();
if (layout.isNull())
{
return;
}
if (layout->LayoutSettings().IsBoundaryTogetherWithNotches())
{
QVector<VLayoutPassmark> const passmarks = piece->GetMappedPassmarks();
bool const seamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
bool const builtInSeamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
VBoundary boundary(seamLinePoints, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(piece->GetName());
if (piece->IsShowFullPiece())
{ {
return; boundary.SetMirrorLine(piece->GetMappedSeamMirrorLine());
} }
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
VPLayoutPtr layout = piece->Layout(); QVector<QPointF> combinedBoundary;
if (layout.isNull()) for (const auto &item : sequence)
{
return;
}
if (layout->LayoutSettings().IsBoundaryTogetherWithNotches())
{
QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks();
bool seamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = piece->IsSeamAllowance() && piece->IsSeamAllowanceBuiltIn();
VBoundary boundary(seamLinePoints, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(piece->GetName());
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
QVector<QPointF> combinedBoundary;
for (const auto &item : sequence)
{
const auto path = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints;
CastTo(path, convertedPoints);
combinedBoundary += convertedPoints;
}
m_seamLine.addPolygon(QPolygonF(combinedBoundary));
m_seamLine.closeSubpath();
}
else
{ {
const auto path = item.item.value<VLayoutPiecePath>().Points();
QVector<QPointF> convertedPoints; QVector<QPointF> convertedPoints;
CastTo(seamLinePoints, convertedPoints); CastTo(path, convertedPoints);
combinedBoundary += convertedPoints;
m_seamLine.addPolygon(QPolygonF(convertedPoints));
m_seamLine.closeSubpath();
} }
if (painter != nullptr) m_seamLine.addPolygon(QPolygonF(combinedBoundary));
{ m_seamLine.closeSubpath();
painter->save(); }
painter->setBrush(piece->IsSelected() ? SelectionBrush() : NoBrush()); else
painter->drawPath(m_seamLine); {
painter->restore(); QVector<QPointF> convertedPoints;
} CastTo(seamLinePoints, convertedPoints);
m_seamLine.addPolygon(QPolygonF(convertedPoints));
m_seamLine.closeSubpath();
}
if (painter != nullptr)
{
painter->save();
painter->setBrush(piece->IsSelected() ? SelectionBrush() : NoBrush());
painter->drawPath(m_seamLine);
painter->restore();
} }
} }
@ -796,7 +739,7 @@ void VPGraphicsPiece::PaintCuttingLine(QPainter *painter, const VPPiecePtr &piec
{ {
if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn()) if (piece->IsSeamAllowance() && not piece->IsSeamAllowanceBuiltIn())
{ {
QVector<VLayoutPoint> cuttingLinepoints = piece->GetMappedSeamAllowancePoints(); QVector<VLayoutPoint> cuttingLinepoints = piece->GetMappedFullSeamAllowancePoints();
if (cuttingLinepoints.isEmpty()) if (cuttingLinepoints.isEmpty())
{ {
return; return;
@ -817,6 +760,10 @@ void VPGraphicsPiece::PaintCuttingLine(QPainter *painter, const VPPiecePtr &piec
VBoundary boundary(cuttingLinepoints, seamAllowance, builtInSeamAllowance); VBoundary boundary(cuttingLinepoints, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(piece->GetName()); boundary.SetPieceName(piece->GetName());
if (piece->IsShowFullPiece())
{
boundary.SetMirrorLine(piece->GetMappedSeamAllowanceMirrorLine());
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
QVector<QPointF> combinedBoundary; QVector<QPointF> combinedBoundary;
@ -853,11 +800,22 @@ void VPGraphicsPiece::PaintCuttingLine(QPainter *painter, const VPPiecePtr &piec
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintInternalPaths(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintInternalPaths(QPainter *painter, const VPPiecePtr &piece)
{ {
QVector<VLayoutPiecePath> internalPaths = piece->GetInternalPaths(); QVector<VLayoutPiecePath> const internalPaths = piece->GetInternalPaths();
for (const auto &piecePath : internalPaths) for (const auto &piecePath : internalPaths)
{ {
QPainterPath path = piece->GetMatrix().map(piecePath.GetPainterPath()); QPainterPath path = piece->GetMatrix().map(piecePath.GetPainterPath());
if (!piecePath.IsNotMirrored() && piece->IsShowFullPiece() && !piece->GetSeamMirrorLine().isNull())
{
QVector<VLayoutPoint> points = piecePath.Points();
const QTransform matrix = VGObject::FlippingMatrix(piece->GetSeamMirrorLine());
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const VLayoutPoint &point) { return VAbstractPiece::MapPoint(point, matrix); });
QVector<QPointF> casted;
CastTo(points, casted);
path.addPath(piece->GetMatrix().map(VPiecePath::MakePainterPath(casted)));
}
if (painter != nullptr) if (painter != nullptr)
{ {
painter->save(); painter->save();
@ -874,7 +832,7 @@ void VPGraphicsPiece::PaintInternalPaths(QPainter *painter, const VPPiecePtr &pi
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintPassmarks(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintPassmarks(QPainter *painter, const VPPiecePtr &piece)
{ {
VPLayoutPtr layout = piece->Layout(); VPLayoutPtr const layout = piece->Layout();
if (layout.isNull()) if (layout.isNull())
{ {
return; return;
@ -885,37 +843,67 @@ void VPGraphicsPiece::PaintPassmarks(QPainter *painter, const VPPiecePtr &piece)
return; return;
} }
QVector<VLayoutPassmark> passmarks = piece->GetMappedPassmarks(); QVector<VLayoutPassmark> const passmarks = piece->GetMappedPassmarks();
for (auto &passmark : passmarks) for (const auto &passmark : passmarks)
{ {
QPainterPath passmarkPath; QPainterPath passmarkPath;
for (auto &line : passmark.lines) for (const auto &line : passmark.lines)
{ {
passmarkPath.moveTo(line.p1()); passmarkPath.moveTo(line.p1());
passmarkPath.lineTo(line.p2()); passmarkPath.lineTo(line.p2());
} }
m_passmarks.addPath(passmarkPath);
QLineF const seamAllowanceMirrorLine = piece->GetMappedSeamAllowanceMirrorLine();
if (!seamAllowanceMirrorLine.isNull() && piece->IsShowFullPiece())
{
if (!VGObject::IsPointOnLineviaPDP(passmark.baseLine.p1(), seamAllowanceMirrorLine.p1(),
seamAllowanceMirrorLine.p2()))
{
QPainterPath mirroredPassmaksPath;
for (const auto &line : passmark.lines)
{
mirroredPassmaksPath.moveTo(line.p1());
mirroredPassmaksPath.lineTo(line.p2());
}
const QTransform matrix = VGObject::FlippingMatrix(seamAllowanceMirrorLine);
m_passmarks.addPath(matrix.map(mirroredPassmaksPath));
}
}
if (painter != nullptr) if (painter != nullptr)
{ {
painter->save(); painter->save();
painter->setBrush(NoBrush()); painter->setBrush(NoBrush());
painter->drawPath(passmarkPath); painter->drawPath(m_passmarks);
painter->restore(); painter->restore();
} }
m_passmarks.addPath(passmarkPath);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintPlaceLabels(QPainter *painter, const VPPiecePtr &piece) void VPGraphicsPiece::PaintPlaceLabels(QPainter *painter, const VPPiecePtr &piece)
{ {
QVector<VLayoutPlaceLabel> placeLabels = piece->GetPlaceLabels(); QVector<VLayoutPlaceLabel> const placeLabels = piece->GetPlaceLabels();
for (auto &placeLabel : placeLabels) for (const auto &placeLabel : placeLabels)
{ {
QPainterPath path = QPainterPath path =
VAbstractPiece::LabelShapePath(piece->MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(placeLabel))); VAbstractPiece::LabelShapePath(piece->MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(placeLabel)));
if (!placeLabel.IsNotMirrored() && piece->IsShowFullPiece() && !piece->GetSeamMirrorLine().isNull())
{
PlaceLabelImg shape = VAbstractPiece::PlaceLabelShape(placeLabel);
const QTransform matrix = VGObject::FlippingMatrix(piece->GetSeamMirrorLine());
for (auto &points : shape)
{
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const VLayoutPoint &point) { return VAbstractPiece::MapPoint(point, matrix); });
}
path.addPath(VAbstractPiece::LabelShapePath(piece->MapPlaceLabelShape(shape)));
}
if (painter != nullptr) if (painter != nullptr)
{ {
painter->save(); painter->save();
@ -955,6 +943,127 @@ void VPGraphicsPiece::PaintStickyPath(QPainter *painter)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintMirrorLine(QPainter *painter, const VPPiecePtr &piece)
{
if (piece->IsShowFullPiece())
{
bool mirrorFlag = false;
QPainterPath mirrorLinePath;
if (not piece->IsSeamAllowance() || piece->IsSeamAllowanceBuiltIn())
{
QLineF const seamMirrorLine = piece->GetMappedSeamMirrorLine();
if (!seamMirrorLine.isNull())
{
QPainterPath mirrorPath;
mirrorPath.moveTo(seamMirrorLine.p1());
mirrorPath.lineTo(seamMirrorLine.p2());
mirrorLinePath.addPath(mirrorPath);
mirrorFlag = true;
}
}
else if (not piece->IsSeamAllowanceBuiltIn())
{
QLineF const seamAllowanceMirrorLine = piece->GetMappedSeamAllowanceMirrorLine();
if (!seamAllowanceMirrorLine.isNull())
{
QPainterPath mirrorPath;
mirrorPath.moveTo(seamAllowanceMirrorLine.p1());
mirrorPath.lineTo(seamAllowanceMirrorLine.p2());
mirrorLinePath.addPath(mirrorPath);
mirrorFlag = true;
}
}
if (mirrorFlag && painter != nullptr)
{
painter->save();
QPen pen = painter->pen();
pen.setStyle(Qt::DashDotLine);
painter->setPen(pen);
painter->drawPath(mirrorLinePath);
painter->restore();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::PaintFoldLine(QPainter *painter, const VPPiecePtr &piece)
{
if (piece->GetFoldLineType() == FoldLineType::None)
{
return;
}
VFoldLine const fLine = piece->FoldLine();
QVector<QPainterPath> const shape = fLine.FoldLinePath();
if (shape.isEmpty())
{
return;
}
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
if (!m_textAsPaths && !settings->GetSingleStrokeOutlineFont() && !settings->GetSingleLineFonts())
{
if (m_foldLineLabelText == nullptr)
{
m_foldLineLabelText = new QGraphicsSimpleTextItem(this);
}
fLine.UpdateFoldLineLabel(m_foldLineLabelText);
}
else
{
if (m_foldLineLabelText != nullptr)
{
m_foldLineLabelText->setVisible(false);
}
}
const bool singleLineFont = settings->GetSingleStrokeOutlineFont() || settings->GetSingleLineFonts();
if (piece->GetFoldLineType() == FoldLineType::ThreeDots || piece->GetFoldLineType() == FoldLineType::ThreeX ||
piece->GetFoldLineType() == FoldLineType::TwoArrows)
{
m_foldLineMarkPath.addPath(shape.constFirst());
}
else if (piece->GetFoldLineType() == FoldLineType::Text)
{
if (singleLineFont || m_textAsPaths)
{
m_foldLineLabelPath.addPath(shape.constFirst());
}
}
else
{
m_foldLineMarkPath.addPath(shape.constFirst());
if (shape.size() > 1 && (singleLineFont || m_textAsPaths))
{
m_foldLineLabelPath.addPath(shape.constLast());
}
}
if (painter != nullptr)
{
painter->save();
painter->setBrush(Qt::SolidPattern);
painter->drawPath(m_foldLineMarkPath);
painter->restore();
qreal const penWidth = VPApplication::VApp()->PuzzleSettings()->GetLayoutLineWidth();
painter->save();
QPen pen = painter->pen();
pen.setWidthF(penWidth * qMin(piece->GetXScale(), piece->GetYScale()));
painter->setPen(pen);
painter->setBrush(singleLineFont ? Qt::NoBrush : Qt::SolidPattern);
painter->drawPath(m_foldLineLabelPath);
painter->restore();
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPGraphicsPiece::GroupMove(const QPointF &pos) void VPGraphicsPiece::GroupMove(const QPointF &pos)
{ {

View File

@ -109,6 +109,9 @@ private:
QVector<QPointF> m_stickyPoints{}; QVector<QPointF> m_stickyPoints{};
QPainterPath m_stickyPath{}; QPainterPath m_stickyPath{};
QPainterPath m_foldLineMarkPath{};
QPainterPath m_foldLineLabelPath{};
bool m_hasStickyPosition{false}; bool m_hasStickyPosition{false};
qreal m_stickyTranslateX{0}; qreal m_stickyTranslateX{0};
qreal m_stickyTranslateY{0}; qreal m_stickyTranslateY{0};
@ -120,6 +123,7 @@ private:
VGraphicsFillItem *m_grainlineItem{nullptr}; VGraphicsFillItem *m_grainlineItem{nullptr};
QVector<QGraphicsPathItem *> m_labelPathItems{}; QVector<QGraphicsPathItem *> m_labelPathItems{};
QVector<QGraphicsSimpleTextItem *> m_labelTextItems{}; QVector<QGraphicsSimpleTextItem *> m_labelTextItems{};
QGraphicsSimpleTextItem *m_foldLineLabelText{nullptr};
void InitLabels(); void InitLabels();
void InitPieceLabelSVGFont(const QVector<QPointF> &labelShape, const VTextManager &tm); void InitPieceLabelSVGFont(const QVector<QPointF> &labelShape, const VTextManager &tm);
@ -133,6 +137,8 @@ private:
void PaintPassmarks(QPainter *painter, const VPPiecePtr &piece); void PaintPassmarks(QPainter *painter, const VPPiecePtr &piece);
void PaintPlaceLabels(QPainter *painter, const VPPiecePtr &piece); void PaintPlaceLabels(QPainter *painter, const VPPiecePtr &piece);
void PaintStickyPath(QPainter *painter); void PaintStickyPath(QPainter *painter);
void PaintMirrorLine(QPainter *painter, const VPPiecePtr &piece);
void PaintFoldLine(QPainter *painter, const VPPiecePtr &piece);
void GroupMove(const QPointF &pos); void GroupMove(const QPointF &pos);

View File

@ -29,11 +29,65 @@
#include "vpgraphicssheet.h" #include "vpgraphicssheet.h"
#include "../layout/vplayout.h" #include "../layout/vplayout.h"
#include "../layout/vpsheet.h" #include "../layout/vpsheet.h"
#include "qnamespace.h" #include "../vlayout/vlayoutpiece.h"
#include "theme/vscenestylesheet.h" #include "../vmisc/theme/vscenestylesheet.h"
#include "../vptilefactory.h"
#include "../vwidgets/vpiecegrainline.h"
#include "scenedef.h"
#include <QApplication>
#include <QFontMetrics>
#include <QtMath> #include <QtMath>
namespace
{
constexpr qreal foldArrowMargin = 20;
//---------------------------------------------------------------------------------------------------------------------
auto SwapRect(const QRectF &rect) -> QRectF
{
return {rect.center().x() - rect.height() / 2.0, rect.center().y() - rect.width() / 2.0, rect.height(),
rect.width()};
}
//---------------------------------------------------------------------------------------------------------------------
void PaintVerticalFoldShadow(QPainter *painter, const QRectF &sheetRect)
{
QLineF shadowLine(sheetRect.topLeft(), sheetRect.bottomLeft());
shadowLine.setLength(shadowLine.length() * 0.97);
shadowLine.setAngle(shadowLine.angle() - 1.5);
QPointF const shadowP =
VGObject::ClosestPoint(QLineF(sheetRect.topLeft(), sheetRect.bottomLeft()), shadowLine.p2());
painter->drawLine(shadowLine);
painter->drawLine(QLineF(shadowLine.p2(), shadowP));
QPolygonF const shadow{sheetRect.topLeft(), shadowLine.p2(), shadowP, sheetRect.topLeft()};
painter->setBrush(QBrush(VSceneStylesheet::ManualLayoutStyle().SheetFoldShadowColor()));
painter->drawPolygon(shadow);
}
//---------------------------------------------------------------------------------------------------------------------
void PaintHorizontalFoldShadow(QPainter *painter, const QRectF &sheetRect)
{
QLineF shadowLine(sheetRect.topRight(), sheetRect.topLeft());
shadowLine.setLength(shadowLine.length() * 0.97);
shadowLine.setAngle(shadowLine.angle() - 1.5);
QPointF const shadowP = VGObject::ClosestPoint(QLineF(sheetRect.topRight(), sheetRect.topLeft()), shadowLine.p2());
painter->drawLine(shadowLine);
painter->drawLine(QLineF(shadowLine.p2(), shadowP));
QPolygonF const shadow{sheetRect.topRight(), shadowLine.p2(), shadowP, sheetRect.topRight()};
painter->setBrush(QBrush(VSceneStylesheet::ManualLayoutStyle().SheetFoldShadowColor()));
painter->drawPolygon(shadow);
}
} // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
VPGraphicsSheet::VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent) VPGraphicsSheet::VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent)
: QGraphicsItem(parent), : QGraphicsItem(parent),
@ -47,92 +101,22 @@ void VPGraphicsSheet::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
Q_UNUSED(widget); Q_UNUSED(widget);
Q_UNUSED(option); Q_UNUSED(option);
bool ignoreMargins = true; PaintMargins(painter);
PaintBorder(painter);
VPLayoutPtr layout = m_layout.toStrongRef(); PaintFold(painter);
PaintGrid(painter);
if (!layout.isNull())
{
VPSheetPtr sheet = layout->GetFocusedSheet();
if (!sheet.isNull())
{
ignoreMargins = sheet->IgnoreMargins();
}
}
if (m_showMargin && !ignoreMargins)
{
QPen pen(VSceneStylesheet::ManualLayoutStyle().SheetMarginColor(), 1.5, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
pen.setCosmetic(true);
painter->save();
painter->setPen(pen);
painter->drawRect(GetMarginsRect());
painter->restore();
}
QRectF sheetRect = GetSheetRect();
if (m_showBorder)
{
QPen pen(VSceneStylesheet::ManualLayoutStyle().SheetBorderColor(), 1.5, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
pen.setCosmetic(true);
painter->save();
painter->setPen(pen);
painter->drawRect(sheetRect);
painter->restore();
}
if (not layout.isNull() && layout->LayoutSettings().GetShowGrid())
{
QPen pen(VSceneStylesheet::ManualLayoutStyle().SheetGridColor(), 1.5, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
pen.setCosmetic(true);
painter->save();
painter->setPen(pen);
qreal colWidth = layout->LayoutSettings().GetGridColWidth();
if (colWidth > 0)
{
qreal colX = colWidth;
while (colX < sheetRect.right())
{
QLineF line = QLineF(colX, 0, colX, sheetRect.bottom());
painter->drawLine(line);
colX += colWidth;
}
}
qreal rowHeight = layout->LayoutSettings().GetGridRowHeight();
if (rowHeight > 0)
{
qreal rowY = rowHeight;
while (rowY < sheetRect.bottom())
{
QLineF line = QLineF(0, rowY, sheetRect.right(), rowY);
painter->drawLine(line);
rowY += rowHeight;
}
}
painter->restore();
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsSheet::GetSheetRect() const -> QRectF auto VPGraphicsSheet::GetSheetRect() const -> QRectF
{ {
VPLayoutPtr layout = m_layout.toStrongRef(); VPLayoutPtr const layout = m_layout.toStrongRef();
if (layout.isNull()) if (layout.isNull())
{ {
return {}; return {};
} }
VPSheetPtr sheet = layout->GetFocusedSheet(); VPSheetPtr const sheet = layout->GetFocusedSheet();
if (sheet.isNull()) if (sheet.isNull())
{ {
return {}; return {};
@ -143,13 +127,13 @@ auto VPGraphicsSheet::GetSheetRect() const -> QRectF
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsSheet::GetMarginsRect() const -> QRectF auto VPGraphicsSheet::GetMarginsRect() const -> QRectF
{ {
VPLayoutPtr layout = m_layout.toStrongRef(); VPLayoutPtr const layout = m_layout.toStrongRef();
if (layout.isNull()) if (layout.isNull())
{ {
return {}; return {};
} }
VPSheetPtr sheet = layout->GetFocusedSheet(); VPSheetPtr const sheet = layout->GetFocusedSheet();
if (sheet.isNull()) if (sheet.isNull())
{ {
return {}; return {};
@ -175,8 +159,321 @@ void VPGraphicsSheet::RefreshBoundingRect()
prepareGeometryChange(); prepareGeometryChange();
} }
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::PaintVerticalFold(QPainter *painter, const QRectF &sheetRect) const
{
VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull() && layout->LayoutSettings().IsCutOnFold())
{
QString const foldText = FoldText();
painter->save();
QFont font = QApplication::font();
font.setPointSize(foldFontSize);
painter->setFont(font);
QRectF textRect = painter->fontMetrics().boundingRect(foldText);
int const textDescent = painter->fontMetrics().descent();
QPointF const textPosition(sheetRect.center().x() - textRect.width() / 2.,
sheetRect.topLeft().y() - foldTextMargin - textDescent);
painter->drawText(textPosition, foldText);
textRect.translate(sheetRect.center() - textRect.center());
textRect.translate(0, -(sheetRect.center().y() - sheetRect.topLeft().y()) - foldTextMargin -
textRect.height() / 2.);
// painter->drawRect(textRect); // uncomment for debug
painter->restore();
if (sheetRect.width() >= textRect.width() * 2)
{
qreal const baseY = textRect.center().y();
qreal const arrowMargin = foldArrowMargin + textRect.width() / 2.;
QLineF const leftLine(QPointF(sheetRect.topLeft().x(), baseY),
QPointF(sheetRect.center().x() - arrowMargin, baseY));
VPieceGrainline const leftArrow(leftLine, GrainlineArrowDirection::oneWayDown);
QPainterPath leftArrowPath = VLayoutPiece::GrainlinePath(leftArrow.Shape());
leftArrowPath.setFillRule(Qt::WindingFill);
painter->save();
QPen pen = painter->pen();
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter->setPen(pen);
painter->setBrush(QBrush(pen.color(), Qt::SolidPattern));
painter->drawPath(leftArrowPath);
painter->restore();
QLineF const rightLine(QPointF(sheetRect.center().x() + arrowMargin, baseY),
QPointF(sheetRect.topRight().x(), baseY));
VPieceGrainline const rightArrow(rightLine, GrainlineArrowDirection::oneWayUp);
QPainterPath rightArrowPath = VLayoutPiece::GrainlinePath(rightArrow.Shape());
rightArrowPath.setFillRule(Qt::WindingFill);
painter->save();
pen = painter->pen();
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter->setPen(pen);
painter->setBrush(QBrush(pen.color(), Qt::SolidPattern));
painter->drawPath(rightArrowPath);
painter->restore();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::PaintHorizontalFold(QPainter *painter, const QRectF &sheetRect) const
{
VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull() && layout->LayoutSettings().IsCutOnFold())
{
QString const foldText = FoldText();
painter->save();
QFont font = QApplication::font();
font.setPointSize(foldFontSize);
painter->setFont(font);
QRectF const textRect = painter->fontMetrics().boundingRect(foldText);
// int const textAscent = painter->fontMetrics().ascent();
int const textDescent = painter->fontMetrics().descent();
QPointF const textPosition(sheetRect.center().x() - textRect.width() / 2.,
sheetRect.center().y() - sheetRect.width() / 2. - foldTextMargin - textDescent);
painter->translate(sheetRect.center());
painter->rotate(90);
painter->translate(-sheetRect.center());
painter->drawText(textPosition, foldText);
painter->restore();
QRectF swappedRect = SwapRect(textRect);
swappedRect.translate(sheetRect.center() - swappedRect.center());
swappedRect.translate(
(sheetRect.topRight().x() - sheetRect.center().x()) + foldTextMargin + textRect.height() / 2., 0);
// painter->drawRect(swappedRect); // uncomment for debug
if (sheetRect.height() >= textRect.width() * 2)
{
// qreal const baseX = sheetRect.topRight().x() + foldTextMargin + textDescent + textAscent / 2.;
qreal const baseX = swappedRect.center().x();
qreal const arrowMargin = foldArrowMargin + textRect.width() / 2.;
QLineF const leftLine(QPointF(baseX, sheetRect.topRight().y()),
QPointF(baseX, sheetRect.center().y() - arrowMargin));
VPieceGrainline const leftArrow(leftLine, GrainlineArrowDirection::oneWayDown);
QPainterPath leftArrowPath = VLayoutPiece::GrainlinePath(leftArrow.Shape());
leftArrowPath.setFillRule(Qt::WindingFill);
painter->save();
QPen pen = painter->pen();
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter->setPen(pen);
painter->setBrush(QBrush(pen.color(), Qt::SolidPattern));
painter->drawPath(leftArrowPath);
painter->restore();
QLineF const rightLine(QPointF(baseX, sheetRect.center().y() + arrowMargin),
QPointF(baseX, sheetRect.bottomRight().y()));
VPieceGrainline const rightArrow(rightLine, GrainlineArrowDirection::oneWayUp);
QPainterPath rightArrowPath = VLayoutPiece::GrainlinePath(rightArrow.Shape());
rightArrowPath.setFillRule(Qt::WindingFill);
painter->save();
pen = painter->pen();
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter->setPen(pen);
painter->setBrush(QBrush(pen.color(), Qt::SolidPattern));
painter->drawPath(rightArrowPath);
painter->restore();
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::PaintMargins(QPainter *painter) const
{
VPLayoutPtr const layout = m_layout.toStrongRef();
if (layout.isNull())
{
return;
}
bool ignoreMargins = true;
VPSheetPtr const sheet = layout->GetFocusedSheet();
if (!sheet.isNull())
{
ignoreMargins = sheet->IgnoreMargins();
}
if (m_showMargin && !ignoreMargins)
{
QPen pen(VSceneStylesheet::ManualLayoutStyle().SheetMarginColor(), 1.5, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
pen.setCosmetic(true);
painter->save();
painter->setPen(pen);
painter->drawRect(GetMarginsRect());
painter->restore();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::PaintBorder(QPainter *painter) const
{
QRectF const sheetRect = GetSheetRect();
if (m_showBorder)
{
QPen pen(VSceneStylesheet::ManualLayoutStyle().SheetBorderColor(), 1.5, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
pen.setCosmetic(true);
painter->save();
painter->setPen(pen);
painter->drawRect(sheetRect);
VPLayoutPtr const layout = m_layout.toStrongRef();
if (!layout.isNull() && layout->LayoutSettings().IsCutOnFold())
{
if (sheetRect.width() >= sheetRect.height())
{
PaintVerticalFoldShadow(painter, sheetRect);
}
else
{
PaintHorizontalFoldShadow(painter, sheetRect);
}
}
painter->restore();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::PaintFold(QPainter *painter) const
{
VPLayoutPtr const layout = m_layout.toStrongRef();
if (!layout.isNull() && layout->LayoutSettings().IsCutOnFold())
{
QRectF const sheetRect = GetSheetRect();
QRectF const foldField = m_showBorder ? sheetRect : FoldField(GetMarginsRect());
if (sheetRect.width() >= sheetRect.height())
{
PaintVerticalFold(painter, foldField);
}
else
{
PaintHorizontalFold(painter, foldField);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VPGraphicsSheet::PaintGrid(QPainter *painter) const
{
VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull() && layout->LayoutSettings().GetShowGrid())
{
QPen pen(VSceneStylesheet::ManualLayoutStyle().SheetGridColor(), 1.5, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin);
pen.setCosmetic(true);
painter->save();
painter->setPen(pen);
QRectF const sheetRect = GetSheetRect();
qreal const colWidth = layout->LayoutSettings().GetGridColWidth();
if (colWidth > 0)
{
qreal colX = colWidth;
while (colX < sheetRect.right())
{
QLineF const line = QLineF(colX, 0, colX, sheetRect.bottom());
painter->drawLine(line);
colX += colWidth;
}
}
qreal const rowHeight = layout->LayoutSettings().GetGridRowHeight();
if (rowHeight > 0)
{
qreal rowY = rowHeight;
while (rowY < sheetRect.bottom())
{
QLineF const line = QLineF(0, rowY, sheetRect.right(), rowY);
painter->drawLine(line);
rowY += rowHeight;
}
}
painter->restore();
}
}
//---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsSheet::FoldField(const QRectF &sheetRect) const -> QRectF
{
VPLayoutPtr const layout = m_layout.toStrongRef();
if (layout.isNull())
{
return sheetRect;
}
VPSheetPtr const sheet = layout->GetFocusedSheet();
qreal const xScale = layout->LayoutSettings().HorizontalScale();
qreal const yScale = layout->LayoutSettings().VerticalScale();
const int nbCol = layout->TileFactory()->ColNb(sheet);
const int nbRow = layout->TileFactory()->RowNb(sheet);
const qreal tilesWidth = (layout->TileFactory()->DrawingAreaWidth() - VPTileFactory::tileStripeWidth) / xScale;
const qreal tilesHeight = (layout->TileFactory()->DrawingAreaHeight() - VPTileFactory::tileStripeWidth) / yScale;
return {sheetRect.topLeft(), QSizeF(nbCol * tilesWidth, nbRow * tilesHeight)};
}
//---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsSheet::FoldText() -> QString
{
return tr("FOLD");
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPGraphicsSheet::boundingRect() const -> QRectF auto VPGraphicsSheet::boundingRect() const -> QRectF
{ {
return GetSheetRect(); QRectF boundingRect = GetSheetRect();
VPLayoutPtr const layout = m_layout.toStrongRef();
if (not layout.isNull() && layout->LayoutSettings().IsCutOnFold())
{
QString const foldText = FoldText();
QFont font = QApplication::font();
font.setPointSize(foldFontSize);
QFontMetrics const metric(font);
QRectF textRect = metric.boundingRect(foldText);
QRectF const foldField = m_showBorder ? boundingRect : FoldField(GetMarginsRect());
if (boundingRect.width() >= boundingRect.height())
{
textRect.translate(foldField.center() - textRect.center());
textRect.translate(0, -(foldField.center().y() - foldField.topLeft().y()) - foldTextMargin -
textRect.height() / 2.);
boundingRect = foldField.united(textRect);
}
else
{
QRectF swappedRect = SwapRect(textRect);
swappedRect.translate(foldField.center() - swappedRect.center());
swappedRect.translate(
(foldField.topRight().x() - foldField.center().x()) + foldTextMargin + textRect.height() / 2., 0);
boundingRect = foldField.united(swappedRect);
}
}
return boundingRect;
} }

View File

@ -29,6 +29,7 @@
#ifndef VPGRAPHICSSHEET_H #ifndef VPGRAPHICSSHEET_H
#define VPGRAPHICSSHEET_H #define VPGRAPHICSSHEET_H
#include <QCoreApplication>
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QPainter> #include <QPainter>
@ -41,6 +42,8 @@ class VPLayout;
class VPGraphicsSheet : public QGraphicsItem class VPGraphicsSheet : public QGraphicsItem
{ {
Q_DECLARE_TR_FUNCTIONS(VPGraphicsSheet) // NOLINT
public: public:
explicit VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent = nullptr); explicit VPGraphicsSheet(const VPLayoutPtr &layout, QGraphicsItem *parent = nullptr);
~VPGraphicsSheet() override = default; ~VPGraphicsSheet() override = default;
@ -65,6 +68,8 @@ public:
void RefreshBoundingRect(); void RefreshBoundingRect();
static auto FoldText() -> QString;
private: private:
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
Q_DISABLE_COPY_MOVE(VPGraphicsSheet) // NOLINT Q_DISABLE_COPY_MOVE(VPGraphicsSheet) // NOLINT
@ -73,6 +78,16 @@ private:
bool m_showMargin{true}; bool m_showMargin{true};
bool m_showBorder{true}; bool m_showBorder{true};
void PaintVerticalFold(QPainter *painter, const QRectF &sheetRect) const;
void PaintHorizontalFold(QPainter *painter, const QRectF &sheetRect) const;
void PaintMargins(QPainter *painter) const;
void PaintBorder(QPainter *painter) const;
void PaintFold(QPainter *painter) const;
void PaintGrid(QPainter *painter) const;
auto FoldField(const QRectF &sheetRect) const -> QRectF;
}; };
#endif // VPGRAPHICSSHEET_H #endif // VPGRAPHICSSHEET_H

View File

@ -147,7 +147,7 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
Q_UNUSED(widget); Q_UNUSED(widget);
Q_UNUSED(option); Q_UNUSED(option);
VPLayoutPtr layout = m_layout.toStrongRef(); VPLayoutPtr const layout = m_layout.toStrongRef();
if (layout.isNull() || not layout->LayoutSettings().GetShowTiles()) if (layout.isNull() || not layout->LayoutSettings().GetShowTiles())
{ {
return; return;
@ -157,14 +157,14 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
Qt::RoundJoin); Qt::RoundJoin);
pen.setCosmetic(true); pen.setCosmetic(true);
pen.setStyle(Qt::DashLine); pen.setStyle(Qt::DashLine);
QBrush noBrush(Qt::NoBrush); QBrush const noBrush(Qt::NoBrush);
painter->setPen(pen); painter->setPen(pen);
painter->setBrush(noBrush); painter->setBrush(noBrush);
qreal xScale = layout->LayoutSettings().HorizontalScale(); qreal const xScale = layout->LayoutSettings().HorizontalScale();
qreal yScale = layout->LayoutSettings().VerticalScale(); qreal const yScale = layout->LayoutSettings().VerticalScale();
VWatermarkData watermarkData = layout->TileFactory()->WatermarkData(); VWatermarkData const watermarkData = layout->TileFactory()->WatermarkData();
auto PaintWatermark = [painter, layout, xScale, yScale, watermarkData](const QRectF &img) auto PaintWatermark = [painter, layout, xScale, yScale, watermarkData](const QRectF &img)
{ {
@ -187,13 +187,13 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
const qreal width = (layout->TileFactory()->DrawingAreaWidth() - VPTileFactory::tileStripeWidth) / xScale; const qreal width = (layout->TileFactory()->DrawingAreaWidth() - VPTileFactory::tileStripeWidth) / xScale;
const qreal height = (layout->TileFactory()->DrawingAreaHeight() - VPTileFactory::tileStripeWidth) / yScale; const qreal height = (layout->TileFactory()->DrawingAreaHeight() - VPTileFactory::tileStripeWidth) / yScale;
VPSheetPtr sheet = layout->GetSheet(m_sheetUuid); VPSheetPtr const sheet = layout->GetSheet(m_sheetUuid);
QMarginsF sheetMargins = SheetMargins(sheet); QMarginsF const sheetMargins = SheetMargins(sheet);
const int nbCol = layout->TileFactory()->ColNb(sheet); const int nbCol = layout->TileFactory()->ColNb(sheet);
const int nbRow = layout->TileFactory()->RowNb(sheet); const int nbRow = layout->TileFactory()->RowNb(sheet);
QFont font = OptimizeFontSizeToFitTextInRect( QFont const font = OptimizeFontSizeToFitTextInRect(
painter, QRectF(sheetMargins.left(), sheetMargins.top(), width / 3., height / 3.), painter, QRectF(sheetMargins.left(), sheetMargins.top(), width / 3., height / 3.),
QString::number(nbRow * nbCol)); QString::number(nbRow * nbCol));
@ -231,7 +231,7 @@ void VPGraphicsTileGrid::paint(QPainter *painter, const QStyleOptionGraphicsItem
if (j < nbRow && i < nbCol) if (j < nbRow && i < nbCol)
{ {
QRectF img(sheetMargins.left() + i * width, sheetMargins.top() + j * height, width, height); QRectF const img(sheetMargins.left() + i * width, sheetMargins.top() + j * height, width, height);
PaintWatermark(img); PaintWatermark(img);
PaintTileNumber(img, i, j); PaintTileNumber(img, i, j);

View File

@ -90,6 +90,11 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
return; return;
} }
if (VAbstractApplication::VApp()->IsWarningMessage(msg))
{
return;
}
// Why on earth didn't Qt want to make failed signal/slot connections qWarning? // Why on earth didn't Qt want to make failed signal/slot connections qWarning?
if ((type == QtDebugMsg) && msg.contains(QStringLiteral("::connect"))) if ((type == QtDebugMsg) && msg.contains(QStringLiteral("::connect")))
{ {

View File

@ -63,6 +63,8 @@
#include "dialogs/vpdialogabout.h" #include "dialogs/vpdialogabout.h"
#include "layout/vppiece.h" #include "layout/vppiece.h"
#include "layout/vpsheet.h" #include "layout/vpsheet.h"
#include "scene/scenedef.h"
#include "scene/vpgraphicssheet.h"
#include "ui_vpmainwindow.h" #include "ui_vpmainwindow.h"
#include "undocommands/vpundoaddsheet.h" #include "undocommands/vpundoaddsheet.h"
#include "undocommands/vpundopiecemove.h" #include "undocommands/vpundopiecemove.h"
@ -249,7 +251,7 @@ void SetPrinterTiledPageSettings(const QSharedPointer<QPrinter> &printer, const
return; return;
} }
QSizeF tileSize = layout->LayoutSettings().GetTilesSize(Unit::Mm); QSizeF const tileSize = layout->LayoutSettings().GetTilesSize(Unit::Mm);
QSizeF pageSize; QSizeF pageSize;
if (not forSheet) if (not forSheet)
@ -258,8 +260,8 @@ void SetPrinterTiledPageSettings(const QSharedPointer<QPrinter> &printer, const
} }
else else
{ {
QPageLayout::Orientation tileOrientation = layout->LayoutSettings().GetTilesOrientation(); QPageLayout::Orientation const tileOrientation = layout->LayoutSettings().GetTilesOrientation();
QPageLayout::Orientation sheetOrientation = sheet->GetSheetOrientation(); QPageLayout::Orientation const sheetOrientation = sheet->GetSheetOrientation();
if (tileOrientation != sheetOrientation) if (tileOrientation != sheetOrientation)
{ {
@ -636,7 +638,6 @@ auto VPMainWindow::SaveLayout(const QString &path, QString &error) -> bool
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::ImportRawLayouts(const QStringList &rawLayouts) void VPMainWindow::ImportRawLayouts(const QStringList &rawLayouts)
{ {
for (const auto &path : rawLayouts) for (const auto &path : rawLayouts)
{ {
if (not ImportRawLayout(path)) if (not ImportRawLayout(path))
@ -782,6 +783,25 @@ void VPMainWindow::InitPropertyTabCurrentPiece()
} }
}); });
connect(ui->checkBoxShowFullPiece, &QCheckBox::toggled, this,
[this](bool checked)
{
QList<VPPiecePtr> selectedPieces = SelectedPieces();
if (selectedPieces.size() == 1)
{
const VPPiecePtr &selectedPiece = selectedPieces.constFirst();
if (not selectedPiece.isNull())
{
if (selectedPiece->IsShowFullPiece() != checked)
{
selectedPiece->SetShowFullPiece(checked);
LayoutWasSaved(false);
emit m_layout->PieceTransformationChanged(selectedPiece);
}
}
}
});
connect(ui->checkBoxCurrentPieceVerticallyFlipped, &QCheckBox::toggled, this, connect(ui->checkBoxCurrentPieceVerticallyFlipped, &QCheckBox::toggled, this,
[this](bool checked) [this](bool checked)
{ {
@ -1197,6 +1217,7 @@ void VPMainWindow::InitPropertyTabLayout()
&VPMainWindow::LayoutWarningPiecesSuperposition_toggled); &VPMainWindow::LayoutWarningPiecesSuperposition_toggled);
connect(ui->checkBoxLayoutWarningPiecesOutOfBound, &QCheckBox::toggled, this, connect(ui->checkBoxLayoutWarningPiecesOutOfBound, &QCheckBox::toggled, this,
&VPMainWindow::LayoutWarningPiecesOutOfBound_toggled); &VPMainWindow::LayoutWarningPiecesOutOfBound_toggled);
connect(ui->checkBoxCutOnFold, &QCheckBox::toggled, this, &VPMainWindow::LayoutCutOnFold_toggled);
connect(ui->checkBoxSheetStickyEdges, &QCheckBox::toggled, this, connect(ui->checkBoxSheetStickyEdges, &QCheckBox::toggled, this,
[this](bool checked) [this](bool checked)
@ -1277,7 +1298,7 @@ void VPMainWindow::SetPropertiesData()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetPropertyTabCurrentPieceData() void VPMainWindow::SetPropertyTabCurrentPieceData()
{ {
QList<VPPiecePtr> selectedPieces = SelectedPieces(); QList<VPPiecePtr> const selectedPieces = SelectedPieces();
ui->labelCurrentPieceNoPieceSelected->setVisible(false); ui->labelCurrentPieceNoPieceSelected->setVisible(false);
@ -1309,12 +1330,16 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
SetCheckBoxValue(ui->checkBoxCurrentPieceVerticallyFlipped, selectedPiece->IsVerticallyFlipped()); SetCheckBoxValue(ui->checkBoxCurrentPieceVerticallyFlipped, selectedPiece->IsVerticallyFlipped());
SetCheckBoxValue(ui->checkBoxCurrentPieceHorizontallyFlipped, selectedPiece->IsHorizontallyFlipped()); SetCheckBoxValue(ui->checkBoxCurrentPieceHorizontallyFlipped, selectedPiece->IsHorizontallyFlipped());
QLineF const seamMirrorLine = selectedPiece->GetSeamMirrorLine();
SetCheckBoxValue(ui->checkBoxShowFullPiece, !seamMirrorLine.isNull() ? selectedPiece->IsShowFullPiece() : true);
ui->checkBoxShowFullPiece->setEnabled(!seamMirrorLine.isNull());
const bool disableFlipping = selectedPiece->IsForbidFlipping() || selectedPiece->IsForceFlipping(); const bool disableFlipping = selectedPiece->IsForbidFlipping() || selectedPiece->IsForceFlipping();
ui->checkBoxCurrentPieceVerticallyFlipped->setDisabled(disableFlipping); ui->checkBoxCurrentPieceVerticallyFlipped->setDisabled(disableFlipping);
if (not ui->checkBoxRelativeTranslation->isChecked()) if (not ui->checkBoxRelativeTranslation->isChecked())
{ {
QRectF rect = PiecesBoundingRect(selectedPieces); QRectF const rect = PiecesBoundingRect(selectedPieces);
ui->doubleSpinBoxCurrentPieceBoxPositionX->setValue( ui->doubleSpinBoxCurrentPieceBoxPositionX->setValue(
UnitConvertor(rect.topLeft().x(), Unit::Px, TranslateUnit())); UnitConvertor(rect.topLeft().x(), Unit::Px, TranslateUnit()));
@ -1332,7 +1357,7 @@ void VPMainWindow::SetPropertyTabCurrentPieceData()
if (not ui->checkBoxRelativeTranslation->isChecked()) if (not ui->checkBoxRelativeTranslation->isChecked())
{ {
QRectF rect = PiecesBoundingRect(selectedPieces); QRectF const rect = PiecesBoundingRect(selectedPieces);
ui->doubleSpinBoxCurrentPieceBoxPositionX->setValue( ui->doubleSpinBoxCurrentPieceBoxPositionX->setValue(
UnitConvertor(rect.topLeft().x(), Unit::Px, TranslateUnit())); UnitConvertor(rect.topLeft().x(), Unit::Px, TranslateUnit()));
@ -1546,6 +1571,7 @@ void VPMainWindow::SetPropertyTabLayoutData()
SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->LayoutSettings().GetStickyEdges()); SetCheckBoxValue(ui->checkBoxSheetStickyEdges, m_layout->LayoutSettings().GetStickyEdges());
SetCheckBoxValue(ui->checkBoxFollowGainline, m_layout->LayoutSettings().GetFollowGrainline()); SetCheckBoxValue(ui->checkBoxFollowGainline, m_layout->LayoutSettings().GetFollowGrainline());
SetCheckBoxValue(ui->checkBoxTogetherWithNotches, m_layout->LayoutSettings().IsBoundaryTogetherWithNotches()); SetCheckBoxValue(ui->checkBoxTogetherWithNotches, m_layout->LayoutSettings().IsBoundaryTogetherWithNotches());
SetCheckBoxValue(ui->checkBoxCutOnFold, m_layout->LayoutSettings().IsCutOnFold());
// set pieces gap // set pieces gap
SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, m_layout->LayoutSettings().GetPiecesGapConverted()); SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, m_layout->LayoutSettings().GetPiecesGapConverted());
@ -1583,6 +1609,7 @@ void VPMainWindow::SetPropertyTabLayoutData()
SetCheckBoxValue(ui->checkBoxSheetStickyEdges, false); SetCheckBoxValue(ui->checkBoxSheetStickyEdges, false);
SetCheckBoxValue(ui->checkBoxFollowGainline, false); SetCheckBoxValue(ui->checkBoxFollowGainline, false);
SetCheckBoxValue(ui->checkBoxTogetherWithNotches, false); SetCheckBoxValue(ui->checkBoxTogetherWithNotches, false);
SetCheckBoxValue(ui->checkBoxCutOnFold, false);
SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, 0); SetDoubleSpinBoxValue(ui->doubleSpinBoxSheetPiecesGap, 0);
@ -2728,7 +2755,7 @@ void VPMainWindow::CleanWaterkmarkEditors()
QMutableListIterator<QPointer<WatermarkWindow>> i(m_watermarkEditors); QMutableListIterator<QPointer<WatermarkWindow>> i(m_watermarkEditors);
while (i.hasNext()) while (i.hasNext())
{ {
QPointer<WatermarkWindow> watermarkEditor = i.next(); QPointer<WatermarkWindow> const watermarkEditor = i.next();
if (watermarkEditor.isNull()) if (watermarkEditor.isNull())
{ {
i.remove(); i.remove();
@ -2761,22 +2788,46 @@ auto VPMainWindow::DrawTilesScheme(QPrinter *printer, QPainter *painter, const V
sheet->SceneData()->PrepareTilesScheme(); sheet->SceneData()->PrepareTilesScheme();
qreal xScale = m_layout->LayoutSettings().HorizontalScale(); qreal const xScale = m_layout->LayoutSettings().HorizontalScale();
qreal yScale = m_layout->LayoutSettings().VerticalScale(); qreal const yScale = m_layout->LayoutSettings().VerticalScale();
qreal width = m_layout->TileFactory()->DrawingAreaWidth(); qreal const width = m_layout->TileFactory()->DrawingAreaWidth();
qreal height = m_layout->TileFactory()->DrawingAreaHeight(); qreal const height = m_layout->TileFactory()->DrawingAreaHeight();
QPageLayout::Orientation tileOrientation = m_layout->LayoutSettings().GetTilesOrientation(); QPageLayout::Orientation const tileOrientation = m_layout->LayoutSettings().GetTilesOrientation();
QPageLayout::Orientation sheetOrientation = sheet->GetSheetOrientation(); QPageLayout::Orientation const sheetOrientation = sheet->GetSheetOrientation();
QRectF sheetRect = sheet->GetMarginsRect(); QRectF const sheetRect = sheet->GetMarginsRect();
const int nbCol = m_layout->TileFactory()->ColNb(sheet); const int nbCol = m_layout->TileFactory()->ColNb(sheet);
const int nbRow = m_layout->TileFactory()->RowNb(sheet); const int nbRow = m_layout->TileFactory()->RowNb(sheet);
QRectF source = QRectF(sheetRect.topLeft(), QSizeF(nbCol * ((width - VPTileFactory::tileStripeWidth) / xScale), qreal const tilesWidth = nbCol * ((width - VPTileFactory::tileStripeWidth) / xScale);
nbRow * ((height - VPTileFactory::tileStripeWidth) / yScale))); qreal const tilesHeight = nbRow * ((height - VPTileFactory::tileStripeWidth) / yScale);
QRectF source;
if (m_layout->LayoutSettings().IsCutOnFold())
{
QFont font = QApplication::font();
font.setPointSize(foldFontSize);
QRectF const textRect = QFontMetrics(font).boundingRect(VPGraphicsSheet::FoldText());
qreal const textHeight = foldTextMargin + textRect.height();
if (sheet->GetSheetOrientation() == QPageLayout::Landscape)
{
QPointF const shift = QPointF(0, textHeight);
source = QRectF(sheetRect.topLeft() - shift, QSizeF(tilesWidth, tilesHeight + textHeight));
}
else
{
source = QRectF(sheetRect.topLeft(), QSizeF(tilesWidth + textHeight, tilesHeight));
}
}
else
{
source = QRectF(sheetRect.topLeft(), QSizeF(tilesWidth, tilesHeight));
}
QRectF target; QRectF target;
if (tileOrientation != sheetOrientation) if (tileOrientation != sheetOrientation)
@ -2787,7 +2838,7 @@ auto VPMainWindow::DrawTilesScheme(QPrinter *printer, QPainter *painter, const V
margins = m_layout->LayoutSettings().GetTilesMargins(); margins = m_layout->LayoutSettings().GetTilesMargins();
} }
QSizeF tilesSize = m_layout->LayoutSettings().GetTilesSize(); QSizeF const tilesSize = m_layout->LayoutSettings().GetTilesSize();
target = QRectF(0, 0, tilesSize.height() - margins.left() - margins.right(), target = QRectF(0, 0, tilesSize.height() - margins.left() - margins.right(),
tilesSize.width() - margins.top() - margins.bottom()); tilesSize.width() - margins.top() - margins.bottom());
} }
@ -2800,7 +2851,7 @@ auto VPMainWindow::DrawTilesScheme(QPrinter *printer, QPainter *painter, const V
sheet->SceneData()->Scene()->render(painter, target, source, Qt::KeepAspectRatio); sheet->SceneData()->Scene()->render(painter, target, source, Qt::KeepAspectRatio);
VWatermarkData watermarkData = m_layout->TileFactory()->WatermarkData(); VWatermarkData const watermarkData = m_layout->TileFactory()->WatermarkData();
if (watermarkData.opacity > 0) if (watermarkData.opacity > 0)
{ {
if (watermarkData.showImage && not watermarkData.path.isEmpty()) if (watermarkData.showImage && not watermarkData.path.isEmpty())
@ -4758,6 +4809,26 @@ void VPMainWindow::LayoutWarningPiecesOutOfBound_toggled(bool checked)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::LayoutCutOnFold_toggled(bool checked)
{
if (not m_layout.isNull())
{
m_layout->LayoutSettings().SetCutOnFold(checked);
LayoutWasSaved(false);
if (checked)
{
VPSheetPtr const sheet = m_layout->GetFocusedSheet();
if (not sheet.isNull())
{
sheet->ValidatePiecesOutOfBound();
}
}
m_graphicsView->RefreshLayout();
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::UpdateShortcuts() void VPMainWindow::UpdateShortcuts()
{ {

View File

@ -294,6 +294,7 @@ private slots:
void LayoutWarningPiecesSuperposition_toggled(bool checked); void LayoutWarningPiecesSuperposition_toggled(bool checked);
void LayoutWarningPiecesOutOfBound_toggled(bool checked); void LayoutWarningPiecesOutOfBound_toggled(bool checked);
void LayoutCutOnFold_toggled(bool checked);
void UpdateShortcuts(); void UpdateShortcuts();

View File

@ -219,7 +219,7 @@
<enum>QTabWidget::Rounded</enum> <enum>QTabWidget::Rounded</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -280,7 +280,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>378</width> <width>378</width>
<height>707</height> <height>736</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_23"> <layout class="QVBoxLayout" name="verticalLayout_23">
@ -488,8 +488,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="object-rotate-right"> <iconset theme="object-rotate-right"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -534,8 +533,7 @@
<string notr="true"/> <string notr="true"/>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="object-rotate-left"> <iconset theme="object-rotate-left"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
@ -623,6 +621,19 @@
<string>Geometry</string> <string>Geometry</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_9"> <layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QCheckBox" name="checkBoxShowFullPiece">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Show full piece</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="checkBoxCurrentPieceVerticallyFlipped"> <widget class="QCheckBox" name="checkBoxCurrentPieceVerticallyFlipped">
<property name="text"> <property name="text">
@ -1729,6 +1740,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkBoxCutOnFold">
<property name="text">
<string>Cut on fold</string>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
@ -2013,8 +2031,7 @@
</widget> </widget>
<action name="actionOpen"> <action name="actionOpen">
<property name="icon"> <property name="icon">
<iconset theme="document-open"> <iconset theme="document-open"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Open</string> <string>&amp;Open</string>
@ -2031,8 +2048,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="document-save"> <iconset theme="document-save"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Save</string> <string>&amp;Save</string>
@ -2049,8 +2065,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="document-save-as"> <iconset theme="document-save-as"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Save &amp;As</string> <string>Save &amp;As</string>
@ -2078,8 +2093,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="application-exit"> <iconset theme="application-exit"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>E&amp;xit</string> <string>E&amp;xit</string>
@ -2093,8 +2107,7 @@
</action> </action>
<action name="actionNew"> <action name="actionNew">
<property name="icon"> <property name="icon">
<iconset theme="document-new"> <iconset theme="document-new"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;New</string> <string>&amp;New</string>
@ -2116,8 +2129,7 @@
</action> </action>
<action name="actionAboutPuzzle"> <action name="actionAboutPuzzle">
<property name="icon"> <property name="icon">
<iconset theme="help-about"> <iconset theme="help-about"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>About &amp;Puzzle</string> <string>About &amp;Puzzle</string>
@ -2148,8 +2160,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-in"> <iconset theme="zoom-in"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Zoom in</string> <string>Zoom in</string>
@ -2160,8 +2171,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-out"> <iconset theme="zoom-out"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Zoom out</string> <string>Zoom out</string>
@ -2172,8 +2182,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-original"> <iconset theme="zoom-original"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Zoom 1:1</string> <string>Zoom 1:1</string>
@ -2184,8 +2193,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="zoom-fit-best"> <iconset theme="zoom-fit-best"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Zoom fit best</string> <string>Zoom fit best</string>
@ -2212,8 +2220,7 @@
</action> </action>
<action name="actionPrintLayout"> <action name="actionPrintLayout">
<property name="icon"> <property name="icon">
<iconset theme="document-print"> <iconset theme="document-print"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print</string> <string>Print</string>
@ -2224,8 +2231,7 @@
</action> </action>
<action name="actionPrintPreviewLayout"> <action name="actionPrintPreviewLayout">
<property name="icon"> <property name="icon">
<iconset theme="document-print-preview"> <iconset theme="document-print-preview"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print preview</string> <string>Print preview</string>
@ -2236,8 +2242,7 @@
</action> </action>
<action name="actionPrintTiledLayout"> <action name="actionPrintTiledLayout">
<property name="icon"> <property name="icon">
<iconset theme="document-print"> <iconset theme="document-print"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print tiled</string> <string>Print tiled</string>
@ -2248,8 +2253,7 @@
</action> </action>
<action name="actionPrintPreviewTiledLayout"> <action name="actionPrintPreviewTiledLayout">
<property name="icon"> <property name="icon">
<iconset theme="document-print-preview"> <iconset theme="document-print-preview"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print preview tiled</string> <string>Print preview tiled</string>
@ -2268,8 +2272,7 @@
</action> </action>
<action name="actionPrintSheet"> <action name="actionPrintSheet">
<property name="icon"> <property name="icon">
<iconset theme="document-print"> <iconset theme="document-print"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print</string> <string>Print</string>
@ -2280,8 +2283,7 @@
</action> </action>
<action name="actionPrintPreviewSheet"> <action name="actionPrintPreviewSheet">
<property name="icon"> <property name="icon">
<iconset theme="document-print-preview"> <iconset theme="document-print-preview"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print preview</string> <string>Print preview</string>
@ -2292,8 +2294,7 @@
</action> </action>
<action name="actionPrintTiledSheet"> <action name="actionPrintTiledSheet">
<property name="icon"> <property name="icon">
<iconset theme="document-print"> <iconset theme="document-print"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print tiled</string> <string>Print tiled</string>
@ -2304,8 +2305,7 @@
</action> </action>
<action name="actionPrintPreviewTiledSheet"> <action name="actionPrintPreviewTiledSheet">
<property name="icon"> <property name="icon">
<iconset theme="document-print-preview"> <iconset theme="document-print-preview"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Print preview tiled</string> <string>Print preview tiled</string>
@ -2324,8 +2324,7 @@
</action> </action>
<action name="actionWatermarkEditor"> <action name="actionWatermarkEditor">
<property name="icon"> <property name="icon">
<iconset theme="document-new"> <iconset theme="document-new"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Editor</string> <string>Editor</string>
@ -2353,8 +2352,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="document-open"> <iconset theme="document-open"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Load</string> <string>Load</string>
@ -2368,8 +2366,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="edit-delete"> <iconset theme="edit-delete"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Remove</string> <string>Remove</string>
@ -2380,8 +2377,7 @@
</action> </action>
<action name="actionZValueBottom"> <action name="actionZValueBottom">
<property name="icon"> <property name="icon">
<iconset theme="go-bottom"> <iconset theme="go-bottom"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Bottom</string> <string>Bottom</string>
@ -2389,8 +2385,7 @@
</action> </action>
<action name="actionZValueDown"> <action name="actionZValueDown">
<property name="icon"> <property name="icon">
<iconset theme="go-down"> <iconset theme="go-down"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Down</string> <string>Down</string>
@ -2398,8 +2393,7 @@
</action> </action>
<action name="actionZValueUp"> <action name="actionZValueUp">
<property name="icon"> <property name="icon">
<iconset theme="go-up"> <iconset theme="go-up"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Up</string> <string>Up</string>
@ -2407,8 +2401,7 @@
</action> </action>
<action name="actionZValueTop"> <action name="actionZValueTop">
<property name="icon"> <property name="icon">
<iconset theme="go-top"> <iconset theme="go-top"/>
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="text"> <property name="text">
<string>Top</string> <string>Top</string>
@ -2441,8 +2434,8 @@
</resources> </resources>
<connections/> <connections/>
<buttongroups> <buttongroups>
<buttongroup name="buttonGroupRotationDirection"/>
<buttongroup name="buttonGroupSheetOrientation"/> <buttongroup name="buttonGroupSheetOrientation"/>
<buttongroup name="buttonGroupRotationDirection"/>
<buttongroup name="buttonGroupTileOrientation"/> <buttongroup name="buttonGroupTileOrientation"/>
</buttongroups> </buttongroups>
</ui> </ui>

View File

@ -343,6 +343,7 @@ void VPLayoutFileReader::ReadControl(const VPLayoutPtr &layout)
layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr)); layout->LayoutSettings().SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr));
layout->LayoutSettings().SetBoundaryTogetherWithNotches( layout->LayoutSettings().SetBoundaryTogetherWithNotches(
ReadAttributeBool(attribs, ML::AttrBoundaryTogetherWithNotches, falseStr)); ReadAttributeBool(attribs, ML::AttrBoundaryTogetherWithNotches, falseStr));
layout->LayoutSettings().SetCutOnFold(ReadAttributeBool(attribs, ML::AttrCutOnFold, falseStr));
readElementText(); readElementText();
} }
@ -518,6 +519,7 @@ void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
piece->SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr)); piece->SetFollowGrainline(ReadAttributeBool(attribs, ML::AttrFollowGrainline, falseStr));
piece->SetSewLineOnDrawing(ReadAttributeBool(attribs, ML::AttrSewLineOnDrawing, falseStr)); piece->SetSewLineOnDrawing(ReadAttributeBool(attribs, ML::AttrSewLineOnDrawing, falseStr));
piece->SetMatrix(StringToTransfrom(ReadAttributeEmptyString(attribs, ML::AttrTransform))); piece->SetMatrix(StringToTransfrom(ReadAttributeEmptyString(attribs, ML::AttrTransform)));
piece->SetShowFullPiece(ReadAttributeBool(attribs, ML::AttrShowFullPiece, trueStr));
const QStringList tags{ const QStringList tags{
ML::TagSeamLine, // 0 ML::TagSeamLine, // 0
@ -526,7 +528,8 @@ void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
ML::TagNotches, // 3 ML::TagNotches, // 3
ML::TagInternalPaths, // 4 ML::TagInternalPaths, // 4
ML::TagMarkers, // 5 ML::TagMarkers, // 5
ML::TagLabels // 6 ML::TagLabels, // 6
ML::TagMirrorLine // 7
}; };
while (readNextStartElement()) while (readNextStartElement())
@ -554,6 +557,9 @@ void VPLayoutFileReader::ReadPiece(const VPPiecePtr &piece)
case 6: // labels case 6: // labels
ReadLabels(piece); ReadLabels(piece);
break; break;
case 7: // mirror line
ReadMirrorLines(piece);
break;
default: default:
qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString())); qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString()));
skipCurrentElement(); skipCurrentElement();
@ -738,11 +744,12 @@ auto VPLayoutFileReader::ReadInternalPath() -> VLayoutPiecePath
VLayoutPiecePath path; VLayoutPiecePath path;
QXmlStreamAttributes attribs = attributes(); QXmlStreamAttributes const attribs = attributes();
path.SetCutPath(ReadAttributeBool(attribs, ML::AttrCut, falseStr)); path.SetCutPath(ReadAttributeBool(attribs, ML::AttrCut, falseStr));
path.SetPenStyle(LineStyleToPenStyle(ReadAttributeString(attribs, ML::AttrPenStyle, TypeLineLine))); path.SetPenStyle(LineStyleToPenStyle(ReadAttributeString(attribs, ML::AttrPenStyle, TypeLineLine)));
path.SetNotMirrored(ReadAttributeBool(attribs, ML::AttrNotMirrored, falseStr));
QVector<VLayoutPoint> shape = ReadLayoutPoints(); QVector<VLayoutPoint> const shape = ReadLayoutPoints();
if (shape.isEmpty()) if (shape.isEmpty())
{ {
throw VException(tr("Error in line %1. Internal path shape is empty.").arg(lineNumber())); throw VException(tr("Error in line %1. Internal path shape is empty.").arg(lineNumber()));
@ -786,14 +793,15 @@ auto VPLayoutFileReader::ReadMarker() -> VLayoutPlaceLabel
VLayoutPlaceLabel marker; VLayoutPlaceLabel marker;
QXmlStreamAttributes attribs = attributes(); QXmlStreamAttributes const attribs = attributes();
QString matrix = ReadAttributeEmptyString(attribs, ML::AttrTransform); QString const matrix = ReadAttributeEmptyString(attribs, ML::AttrTransform);
marker.SetRotationMatrix(StringToTransfrom(matrix)); marker.SetRotationMatrix(StringToTransfrom(matrix));
marker.SetType(static_cast<PlaceLabelType>(ReadAttributeUInt(attribs, ML::AttrType, QChar('0')))); marker.SetType(static_cast<PlaceLabelType>(ReadAttributeUInt(attribs, ML::AttrType, QChar('0'))));
marker.SetCenter(StringToPoint(ReadAttributeEmptyString(attribs, ML::AttrCenter))); marker.SetCenter(StringToPoint(ReadAttributeEmptyString(attribs, ML::AttrCenter)));
marker.SetBox(StringToRect(ReadAttributeEmptyString(attribs, ML::AttrBox))); marker.SetBox(StringToRect(ReadAttributeEmptyString(attribs, ML::AttrBox)));
marker.SetNotMirrored(ReadAttributeBool(attribs, ML::AttrNotMirrored, falseStr));
// cppcheck-suppress unknownMacro // cppcheck-suppress unknownMacro
QT_WARNING_POP QT_WARNING_POP
@ -940,6 +948,54 @@ void VPLayoutFileReader::ReadWatermark(const VPLayoutPtr &layout)
layout->LayoutSettings().SetWatermarkPath(readElementText()); layout->LayoutSettings().SetWatermarkPath(readElementText());
} }
//---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadMirrorLines(const VPPiecePtr &piece)
{
AssertRootTag(ML::TagMirrorLine);
QXmlStreamAttributes const attribs = attributes();
piece->SetFoldLineType(StringToFoldLineType(
ReadAttributeString(attribs, ML::AttrGrainlineType, FoldLineTypeToString(FoldLineType::TwoArrowsTextAbove))));
piece->SetFoldLineHeight(ReadAttributeDouble(attribs, ML::AttrFoldLineHeight, QChar('0')));
piece->SetFoldLineWidth(ReadAttributeDouble(attribs, ML::AttrFoldLineWidth, QChar('0')));
piece->SetFoldLineCenterPosition(ReadAttributeDouble(attribs, ML::AttrFoldLineCenter, QString::number(0.5)));
piece->SetFoldLineLabelFontBold(ReadAttributeBool(attribs, ML::AttrBold, falseStr));
piece->SetFoldLineLabelFontItalic(ReadAttributeBool(attribs, ML::AttrItalic, falseStr));
piece->SetFoldLineLabelAlignment(
ReadAttributeInt(attribs, ML::AttrAlignment, QString::number(static_cast<int>(Qt::AlignHCenter))));
piece->SetFoldLineLabel(ReadAttributeEmptyString(attribs, ML::AttrFoldLineLabel));
piece->SetFoldLineOutlineFont(FontFromString(ReadAttributeEmptyString(attribs, ML::AttrFont)));
QStringList const svgFontData = ReadAttributeEmptyString(attribs, ML::AttrSVGFont).split(','_L1);
if (!svgFontData.isEmpty())
{
piece->SetFoldLineSVGFontFamily(svgFontData.constFirst());
if (svgFontData.size() > 1)
{
piece->SetFoldLineSvgFontSize(svgFontData.at(1).toUInt());
}
}
while (readNextStartElement())
{
if (name() == ML::TagSeamLine)
{
piece->SetSeamMirrorLine(StringToLine(readElementText()));
}
else if (name() == ML::TagSeamAllowance)
{
piece->SetSeamAllowanceMirrorLine(StringToLine(readElementText()));
}
else
{
qCDebug(MLReader, "Ignoring tag %s", qUtf8Printable(name().toString()));
skipCurrentElement();
}
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileReader::ReadLayoutMargins(const VPLayoutPtr &layout) void VPLayoutFileReader::ReadLayoutMargins(const VPLayoutPtr &layout)
{ {

View File

@ -29,9 +29,9 @@
#ifndef VPLAYOUTFILEREADER_H #ifndef VPLAYOUTFILEREADER_H
#define VPLAYOUTFILEREADER_H #define VPLAYOUTFILEREADER_H
#include <QXmlStreamReader>
#include "../ifc/xml/vabstractconverter.h" #include "../ifc/xml/vabstractconverter.h"
#include "../layout/layoutdef.h" #include "../layout/layoutdef.h"
#include <QXmlStreamReader>
#include <QLoggingCategory> #include <QLoggingCategory>
@ -47,9 +47,10 @@ class VLayoutPoint;
class VPLayoutFileReader : public QXmlStreamReader class VPLayoutFileReader : public QXmlStreamReader
{ {
Q_DECLARE_TR_FUNCTIONS(VPLayoutFileReader) // NOLINT Q_DECLARE_TR_FUNCTIONS(VPLayoutFileReader) // NOLINT
public: public:
VPLayoutFileReader()=default; VPLayoutFileReader() = default;
~VPLayoutFileReader()=default; ~VPLayoutFileReader() = default;
auto ReadFile(const VPLayoutPtr &layout, QFile *file) -> bool; auto ReadFile(const VPLayoutPtr &layout, QFile *file) -> bool;
@ -65,7 +66,7 @@ private:
void ReadUnplacedPieces(const VPLayoutPtr &layout); void ReadUnplacedPieces(const VPLayoutPtr &layout);
void ReadSheets(const VPLayoutPtr &layout); void ReadSheets(const VPLayoutPtr &layout);
void ReadSheet(const VPLayoutPtr &layout); void ReadSheet(const VPLayoutPtr &layout);
void ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet=VPSheetPtr()); void ReadPieces(const VPLayoutPtr &layout, const VPSheetPtr &sheet = VPSheetPtr());
void ReadPiece(const VPPiecePtr &piece); void ReadPiece(const VPPiecePtr &piece);
auto ReadLayoutPoint() -> VLayoutPoint; auto ReadLayoutPoint() -> VLayoutPoint;
auto ReadLayoutPoints() -> QVector<VLayoutPoint>; auto ReadLayoutPoints() -> QVector<VLayoutPoint>;
@ -84,7 +85,7 @@ private:
auto ReadLabelLines() -> VTextManager; auto ReadLabelLines() -> VTextManager;
auto ReadLabelLine() -> TextLine; auto ReadLabelLine() -> TextLine;
void ReadWatermark(const VPLayoutPtr &layout); void ReadWatermark(const VPLayoutPtr &layout);
void ReadMirrorLines(const VPPiecePtr &piece);
void ReadLayoutMargins(const VPLayoutPtr &layout); void ReadLayoutMargins(const VPLayoutPtr &layout);
void ReadSheetMargins(const VPSheetPtr &sheet); void ReadSheetMargins(const VPSheetPtr &sheet);
@ -92,17 +93,17 @@ private:
void AssertRootTag(const QString &tag) const; void AssertRootTag(const QString &tag) const;
static auto ReadAttributeString(const QXmlStreamAttributes &attribs, const QString &name, static auto ReadAttributeString(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue)
const QString &defValue) -> QString; -> QString;
static auto ReadAttributeEmptyString(const QXmlStreamAttributes &attribs, const QString &name) -> QString; static auto ReadAttributeEmptyString(const QXmlStreamAttributes &attribs, const QString &name) -> QString;
static auto ReadAttributeBool(const QXmlStreamAttributes &attribs, const QString &name, static auto ReadAttributeBool(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue)
const QString &defValue) -> bool; -> bool;
static auto ReadAttributeDouble(const QXmlStreamAttributes &attribs, const QString &name, static auto ReadAttributeDouble(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue)
const QString &defValue) -> qreal; -> qreal;
static auto ReadAttributeUInt(const QXmlStreamAttributes &attribs, const QString &name, static auto ReadAttributeUInt(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue)
const QString &defValue) -> quint32; -> quint32;
static auto ReadAttributeInt(const QXmlStreamAttributes &attribs, const QString &name, static auto ReadAttributeInt(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue)
const QString &defValue) -> int; -> int;
}; };
#endif // VPLAYOUTFILEREADER_H #endif // VPLAYOUTFILEREADER_H

View File

@ -35,6 +35,8 @@
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vtextmanager.h" #include "../vlayout/vtextmanager.h"
#include "../vmisc/projectversion.h" #include "../vmisc/projectversion.h"
#include "def.h"
#include "qnumeric.h"
#include "vplayoutliterals.h" #include "vplayoutliterals.h"
namespace namespace
@ -174,6 +176,8 @@ void VPLayoutFileWriter::WriteLayoutProperties(const VPLayoutPtr &layout)
SetAttribute(ML::AttrPiecesGap, layout->LayoutSettings().GetPiecesGap()); SetAttribute(ML::AttrPiecesGap, layout->LayoutSettings().GetPiecesGap());
SetAttribute(ML::AttrFollowGrainline, layout->LayoutSettings().GetFollowGrainline()); SetAttribute(ML::AttrFollowGrainline, layout->LayoutSettings().GetFollowGrainline());
SetAttribute(ML::AttrBoundaryTogetherWithNotches, layout->LayoutSettings().IsBoundaryTogetherWithNotches()); SetAttribute(ML::AttrBoundaryTogetherWithNotches, layout->LayoutSettings().IsBoundaryTogetherWithNotches());
SetAttributeOrRemoveIf<bool>(ML::AttrCutOnFold, layout->LayoutSettings().IsCutOnFold(),
[](bool cut) noexcept { return not cut; });
writeEndElement(); // control writeEndElement(); // control
WriteTiles(layout); WriteTiles(layout);
@ -284,6 +288,8 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
[](qreal ys) noexcept { return VFuzzyComparePossibleNulls(ys, 1.0); }); [](qreal ys) noexcept { return VFuzzyComparePossibleNulls(ys, 1.0); });
SetAttributeOrRemoveIf<qreal>(ML::AttrZValue, piece->ZValue(), SetAttributeOrRemoveIf<qreal>(ML::AttrZValue, piece->ZValue(),
[](qreal z) noexcept { return VFuzzyComparePossibleNulls(z, 1.0); }); [](qreal z) noexcept { return VFuzzyComparePossibleNulls(z, 1.0); });
SetAttributeOrRemoveIf<bool>(ML::AttrShowFullPiece, piece->IsShowFullPiece(),
[](bool show) noexcept { return show; });
writeStartElement(ML::TagSeamLine); writeStartElement(ML::TagSeamLine);
QVector<VLayoutPoint> contourPoints = piece->GetContourPoints(); QVector<VLayoutPoint> contourPoints = piece->GetContourPoints();
@ -340,6 +346,8 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
writeStartElement(ML::TagInternalPath); writeStartElement(ML::TagInternalPath);
SetAttribute(ML::AttrCut, path.IsCutPath()); SetAttribute(ML::AttrCut, path.IsCutPath());
SetAttribute(ML::AttrPenStyle, PenStyleToLineStyle(path.PenStyle())); SetAttribute(ML::AttrPenStyle, PenStyleToLineStyle(path.PenStyle()));
SetAttributeOrRemoveIf<bool>(ML::AttrNotMirrored, path.IsNotMirrored(),
[](bool mirrored) noexcept { return mirrored; });
QVector<VLayoutPoint> points = path.Points(); QVector<VLayoutPoint> points = path.Points();
for (auto &point : points) for (auto &point : points)
@ -360,6 +368,8 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
SetAttribute(ML::AttrType, static_cast<int>(label.Type())); SetAttribute(ML::AttrType, static_cast<int>(label.Type()));
SetAttribute(ML::AttrCenter, PointToString(label.Center())); SetAttribute(ML::AttrCenter, PointToString(label.Center()));
SetAttribute(ML::AttrBox, RectToString(label.Box())); SetAttribute(ML::AttrBox, RectToString(label.Box()));
SetAttributeOrRemoveIf<bool>(ML::AttrNotMirrored, label.IsNotMirrored(),
[](bool mirrored) noexcept { return mirrored; });
writeEndElement(); writeEndElement();
} }
writeEndElement(); writeEndElement();
@ -369,6 +379,51 @@ void VPLayoutFileWriter::WritePiece(const VPPiecePtr &piece)
WriteLabel(piece->GetPatternLabelRect(), piece->GetPatternLabelData(), ML::TagPatternLabel); WriteLabel(piece->GetPatternLabelRect(), piece->GetPatternLabelData(), ML::TagPatternLabel);
writeEndElement(); writeEndElement();
QLineF const seamMirrorLine = piece->GetSeamMirrorLine();
QLineF const seamAllowenceMirrorLine = piece->GetSeamAllowanceMirrorLine();
if (!seamMirrorLine.isNull() || !seamAllowenceMirrorLine.isNull())
{
writeStartElement(ML::TagMirrorLine);
SetAttribute(ML::AttrFoldLineType, FoldLineTypeToString(piece->GetFoldLineType()));
SetAttributeOrRemoveIf<qreal>(ML::AttrFoldLineHeight, piece->GetFoldLineHeight(),
[](qreal height) noexcept { return qFuzzyIsNull(height); });
SetAttributeOrRemoveIf<qreal>(ML::AttrFoldLineWidth, piece->GetFoldLineWidth(),
[](qreal width) noexcept { return qFuzzyIsNull(width); });
SetAttributeOrRemoveIf<qreal>(ML::AttrFoldLineCenter, piece->GetFoldLineCenterPosition(),
[](qreal center) noexcept { return VFuzzyComparePossibleNulls(center, 0.5); });
SetAttributeOrRemoveIf<bool>(ML::AttrItalic, piece->IsFoldLineLabelFontItalic(),
[](bool italic) noexcept { return not italic; });
SetAttributeOrRemoveIf<bool>(ML::AttrBold, piece->IsFoldLineLabelFontBold(),
[](bool bold) noexcept { return not bold; });
SetAttributeOrRemoveIf<QString>(ML::AttrFoldLineLabel, piece->GetFoldLineLabel(),
[](const QString &label) noexcept { return label.isEmpty(); });
SetAttributeOrRemoveIf<int>(ML::AttrAlignment, piece->GetFoldLineLabelAlignment(),
[](int alignment) noexcept { return alignment == Qt::AlignHCenter; });
SetAttributeOrRemoveIf<QString>(ML::AttrFont, piece->GetFoldLineOutlineFont().toString(),
[piece](const QString &) { return piece->GetFoldLineLabel().isEmpty(); });
SetAttributeOrRemoveIf<QString>(
ML::AttrSVGFont,
QStringLiteral("%1,%2").arg(piece->GetFoldLineSVGFontFamily()).arg(piece->GetFoldLineSvgFontSize()),
[piece](const QString &) { return piece->GetFoldLineLabel().isEmpty(); });
if (!seamMirrorLine.isNull())
{
writeStartElement(ML::TagSeamLine);
writeCharacters(LineToString(seamMirrorLine));
writeEndElement();
}
if (!seamAllowenceMirrorLine.isNull())
{
writeStartElement(ML::TagSeamAllowance);
writeCharacters(LineToString(seamAllowenceMirrorLine));
writeEndElement();
}
writeEndElement();
}
writeEndElement(); writeEndElement();
} }
@ -389,7 +444,7 @@ void VPLayoutFileWriter::WriteLabelLines(const VTextManager &tm)
{ {
writeStartElement(ML::TagLines); writeStartElement(ML::TagLines);
SetAttribute(ML::AttrFont, tm.GetFont().toString()); SetAttribute(ML::AttrFont, tm.GetFont().toString());
SetAttribute(ML::AttrSVGFont, QStringLiteral("%1,%2").arg(tm.GetSVGFontFamily(), tm.GetSVGFontPointSize())); SetAttribute(ML::AttrSVGFont, QStringLiteral("%1,%2").arg(tm.GetSVGFontFamily()).arg(tm.GetSVGFontPointSize()));
for (int i = 0; i < tm.GetSourceLinesCount(); ++i) for (int i = 0; i < tm.GetSourceLinesCount(); ++i)
{ {

View File

@ -67,6 +67,7 @@ const QString TagLine = QStringLiteral("line"); // NOLINT(ce
const QString TagScale = QStringLiteral("scale"); // NOLINT(cert-err58-cpp) const QString TagScale = QStringLiteral("scale"); // NOLINT(cert-err58-cpp)
const QString TagWatermark = QStringLiteral("watermark"); // NOLINT(cert-err58-cpp) const QString TagWatermark = QStringLiteral("watermark"); // NOLINT(cert-err58-cpp)
const QString TagPoint = QStringLiteral("point"); // NOLINT(cert-err58-cpp) const QString TagPoint = QStringLiteral("point"); // NOLINT(cert-err58-cpp)
const QString TagMirrorLine = QStringLiteral("mirrorLine"); // NOLINT(cert-err58-cpp)
const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp) const QString AttrWarningSuperposition = QStringLiteral("warningSuperposition"); // NOLINT(cert-err58-cpp)
const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp) const QString AttrWarningOutOfBound = QStringLiteral("warningOutOfBound"); // NOLINT(cert-err58-cpp)
@ -123,6 +124,14 @@ const QString AttrY = QStringLiteral("y");
const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp) const QString AttrTurnPoint = QStringLiteral("turnPoint"); // NOLINT(cert-err58-cpp)
const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp) const QString AttrCurvePoint = QStringLiteral("curvePoint"); // NOLINT(cert-err58-cpp)
const QString AttrClockwiseOpening = QStringLiteral("clockwiseOpening"); // NOLINT(cert-err58-cpp) const QString AttrClockwiseOpening = QStringLiteral("clockwiseOpening"); // NOLINT(cert-err58-cpp)
const QString AttrShowFullPiece = QStringLiteral("showFullPiece"); // NOLINT(cert-err58-cpp)
const QString AttrNotMirrored = QStringLiteral("notMirrored"); // NOLINT(cert-err58-cpp)
const QString AttrCutOnFold = QStringLiteral("cutOnFold"); // NOLINT(cert-err58-cpp)
const QString AttrFoldLineType = QStringLiteral("type"); // NOLINT(cert-err58-cpp)
const QString AttrFoldLineHeight = QStringLiteral("height"); // NOLINT(cert-err58-cpp)
const QString AttrFoldLineWidth = QStringLiteral("width"); // NOLINT(cert-err58-cpp)
const QString AttrFoldLineCenter = QStringLiteral("center"); // NOLINT(cert-err58-cpp)
const QString AttrFoldLineLabel = QStringLiteral("label"); // NOLINT(cert-err58-cpp)
const QString oneWayUpStr = QStringLiteral("oneWayUp"); // NOLINT(cert-err58-cpp) const QString oneWayUpStr = QStringLiteral("oneWayUp"); // NOLINT(cert-err58-cpp)
const QString oneWayDownStr = QStringLiteral("oneWayDown"); // NOLINT(cert-err58-cpp) const QString oneWayDownStr = QStringLiteral("oneWayDown"); // NOLINT(cert-err58-cpp)

View File

@ -66,6 +66,7 @@ extern const QString TagLine;
extern const QString TagScale; extern const QString TagScale;
extern const QString TagWatermark; extern const QString TagWatermark;
extern const QString TagPoint; extern const QString TagPoint;
extern const QString TagMirrorLine;
extern const QString AttrWarningSuperposition; extern const QString AttrWarningSuperposition;
extern const QString AttrWarningOutOfBound; extern const QString AttrWarningOutOfBound;
@ -122,6 +123,14 @@ extern const QString AttrY;
extern const QString AttrTurnPoint; extern const QString AttrTurnPoint;
extern const QString AttrCurvePoint; extern const QString AttrCurvePoint;
extern const QString AttrClockwiseOpening; extern const QString AttrClockwiseOpening;
extern const QString AttrShowFullPiece;
extern const QString AttrNotMirrored;
extern const QString AttrCutOnFold;
extern const QString AttrFoldLineType;
extern const QString AttrFoldLineHeight;
extern const QString AttrFoldLineWidth;
extern const QString AttrFoldLineCenter;
extern const QString AttrFoldLineLabel;
extern const QString oneWayUpStr; extern const QString oneWayUpStr;
extern const QString oneWayDownStr; extern const QString oneWayDownStr;

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<pattern labelPrefix="uk">
<!--Pattern created with Valentina v0.7.52.902 (https://smart-pattern.com.ua/).-->
<version>0.9.4</version>
<unit>cm</unit>
<description/>
<notes/>
<measurements/>
<increments/>
<previewCalculations/>
<draw name="Pattern piece 1">
<calculation>
<point id="1" mx="0.264583" my="0.396875" name="А" showLabel="true" type="single" x="0.79375" y="1.05833"/>
<point angle="270" basePoint="1" id="2" length="15" lineColor="black" mx="0.264583" my="0.396875" name="А1" showLabel="true" type="endLine" typeLine="hair"/>
<point angle="0" basePoint="1" id="3" length="20" lineColor="black" mx="0.264583" my="0.396875" name="А2" showLabel="true" type="endLine" typeLine="hair"/>
<point angle="270" basePoint="3" id="4" length="10" lineColor="black" mx="0.264583" my="0.396875" name="А3" showLabel="true" type="endLine" typeLine="hair"/>
<line firstPoint="2" id="5" lineColor="black" secondPoint="4" typeLine="hair"/>
</calculation>
<modeling>
<point id="10" idObject="1" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="11" idObject="3" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="12" idObject="4" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="13" idObject="2" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="15" idObject="1" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="16" idObject="3" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="17" idObject="4" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="18" idObject="2" inUse="false" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="20" idObject="1" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="21" idObject="3" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="22" idObject="4" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="23" idObject="2" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="25" idObject="1" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="26" idObject="3" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="27" idObject="4" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
<point id="28" idObject="2" inUse="true" mx="0.264583" my="0.396875" showLabel="true" type="modeling"/>
</modeling>
<details>
<detail followGrainline="false" forbidFlipping="false" forceFlipping="false" hideMainPath="false" id="14" mx="0" my="0" name="Case 1" seamAllowance="true" sewLineOnDrawing="false" uuid="{410acde1-f2f0-4603-89e9-f2569843673b}" version="2" width="1">
<data annotation="" foldPosition="" height="10" letter="" mx="0" my="0" onFold="false" orientation="" quantity="1" rotation="0" rotationWay="" tilt="" visible="false" width="10"/>
<patternInfo height="10" mx="0" my="0" rotation="0" visible="false" width="10"/>
<grainline arrows="0" length="10" mx="0" my="0" rotation="90" visible="false"/>
<nodes>
<node idObject="10" type="NodePoint"/>
<node idObject="11" type="NodePoint"/>
<node idObject="12" type="NodePoint"/>
<node idObject="13" type="NodePoint"/>
</nodes>
<mirrorLine fontSize="6" p1="12" p2="13" type="none"/>
</detail>
<detail followGrainline="false" forbidFlipping="false" forceFlipping="false" hideMainPath="false" id="19" mx="31.0026" my="-0.303098" name="Case 2" seamAllowance="true" sewLineOnDrawing="false" uuid="{5ce7b61f-1d49-4ef3-8922-521b9aac6b49}" version="2" width="1">
<data annotation="" foldPosition="" height="10" letter="" mx="0" my="0" onFold="false" orientation="" quantity="1" rotation="0" rotationWay="" tilt="" visible="false" width="10"/>
<patternInfo height="10" mx="0" my="0" rotation="0" visible="false" width="10"/>
<grainline arrows="0" length="10" mx="0" my="0" rotation="90" visible="false"/>
<nodes>
<node idObject="16" type="NodePoint"/>
<node idObject="17" type="NodePoint"/>
<node idObject="18" type="NodePoint"/>
<node idObject="15" type="NodePoint"/>
</nodes>
<mirrorLine fontSize="6" p1="17" p2="18" type="none"/>
</detail>
<detail followGrainline="false" forbidFlipping="false" forceFlipping="false" hideMainPath="false" id="24" mx="66.2511" my="-0.29709" name="Case 3" seamAllowance="true" sewLineOnDrawing="false" uuid="{cce244ba-8361-44ef-841a-dea47de205c7}" version="2" width="1">
<data annotation="" foldPosition="" height="10" letter="" mx="0" my="0" onFold="false" orientation="" quantity="1" rotation="0" rotationWay="" tilt="" visible="false" width="10"/>
<patternInfo height="10" mx="0" my="0" rotation="0" visible="false" width="10"/>
<grainline arrows="0" length="10" mx="0" my="0" rotation="90" visible="false"/>
<nodes>
<node idObject="22" type="NodePoint"/>
<node idObject="23" type="NodePoint"/>
<node idObject="20" type="NodePoint"/>
<node idObject="21" type="NodePoint"/>
</nodes>
<mirrorLine fontSize="6" p1="22" p2="23" type="none"/>
</detail>
<detail followGrainline="false" forbidFlipping="false" forceFlipping="false" hideMainPath="false" id="29" mx="101.666" my="0" name="Case 4" seamAllowance="true" sewLineOnDrawing="false" uuid="{c73f153b-9a1a-4a09-9117-b4b8ab4808a7}" version="2" width="1">
<data annotation="" foldPosition="" height="10" letter="" mx="0" my="0" onFold="false" orientation="" quantity="1" rotation="0" rotationWay="" tilt="" visible="false" width="10"/>
<patternInfo height="10" mx="0" my="0" rotation="0" visible="false" width="10"/>
<grainline arrows="0" length="10" mx="0" my="0" rotation="90" visible="false"/>
<nodes>
<node idObject="28" type="NodePoint"/>
<node idObject="25" type="NodePoint"/>
<node idObject="26" type="NodePoint"/>
<node idObject="27" type="NodePoint"/>
</nodes>
<mirrorLine fontSize="6" p1="27" p2="28" type="none"/>
</detail>
</details>
<groups/>
</draw>
</pattern>

View File

@ -2850,8 +2850,8 @@ void VToolOptionsPropertyBrowser::ShowOptionsToolTrueDarts(QGraphicsItem *item)
AddPropertyParentPointName(i->BaseLineP1Name(), tr("First base point:"), AttrFirstPoint); AddPropertyParentPointName(i->BaseLineP1Name(), tr("First base point:"), AttrFirstPoint);
AddPropertyParentPointName(i->BaseLineP2Name(), tr("Second base point:"), AttrSecondPoint); AddPropertyParentPointName(i->BaseLineP2Name(), tr("Second base point:"), AttrSecondPoint);
AddPropertyParentPointName(i->DartP1Name(), tr("First dart point:"), AttrDartP1); AddPropertyParentPointName(i->DartP1Name(), tr("First dart point:"), AttrDartP1);
AddPropertyParentPointName(i->DartP2Name(), tr("First dart point:"), AttrDartP2); AddPropertyParentPointName(i->DartP2Name(), tr("Second dart point:"), AttrDartP2);
AddPropertyParentPointName(i->DartP3Name(), tr("First dart point:"), AttrDartP3); AddPropertyParentPointName(i->DartP3Name(), tr("Third dart point:"), AttrDartP3);
AddPropertyText(tr("Notes:"), i->GetNotes(), AttrNotes); AddPropertyText(tr("Notes:"), i->GetNotes(), AttrNotes);
} }

View File

@ -323,7 +323,7 @@ void PreferencesPatternPage::InitLabelFontSizes()
ui->comboBoxLabelFontSize->clear(); ui->comboBoxLabelFontSize->clear();
// Get the available font sizes // Get the available font sizes
QList<int> sizes = QFontDatabase::standardSizes(); QList<int> const sizes = QFontDatabase::standardSizes();
for (auto size : sizes) for (auto size : sizes)
{ {
if (size >= VCommonSettings::MinPieceLabelFontPointSize()) if (size >= VCommonSettings::MinPieceLabelFontPointSize())

View File

@ -126,7 +126,6 @@ DialogSaveLayout::DialogSaveLayout(int count, Draw mode, const QString &fileName
else else
{ {
RemoveFormatFromList(LayoutExportFormats::RLD); RemoveFormatFromList(LayoutExportFormats::RLD);
ui->checkBoxTextAsPaths->setVisible(false);
} }
connect(bOk, &QPushButton::clicked, this, &DialogSaveLayout::Save); connect(bOk, &QPushButton::clicked, this, &DialogSaveLayout::Save);
@ -439,9 +438,12 @@ void DialogSaveLayout::ShowExample()
ui->labelOptionsNotAvailable->setVisible(false); ui->labelOptionsNotAvailable->setVisible(false);
ui->checkBoxBinaryDXF->setVisible(false); ui->checkBoxBinaryDXF->setVisible(false);
ui->checkBoxTextAsPaths->setVisible(false); ui->checkBoxTextAsPaths->setVisible(false);
ui->checkBoxTextAsPaths->setEnabled(true);
ui->checkBoxShowGrainline->setVisible(false); ui->checkBoxShowGrainline->setVisible(false);
ui->checkBoxTogetherWithNotches->setVisible(false); ui->checkBoxTogetherWithNotches->setVisible(false);
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
switch (currentFormat) switch (currentFormat)
{ {
case LayoutExportFormats::DXF_AAMA: case LayoutExportFormats::DXF_AAMA:
@ -452,7 +454,12 @@ void DialogSaveLayout::ShowExample()
case LayoutExportFormats::PDFTiled: case LayoutExportFormats::PDFTiled:
ui->groupBoxPaperFormat->setEnabled(true); ui->groupBoxPaperFormat->setEnabled(true);
ui->groupBoxMargins->setEnabled(true); ui->groupBoxMargins->setEnabled(true);
ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout); ui->checkBoxTextAsPaths->setVisible(true);
if (settings->GetSingleLineFonts() || settings->GetSingleStrokeOutlineFont())
{
ui->checkBoxTextAsPaths->setDisabled(true);
ui->checkBoxTextAsPaths->setChecked(true);
}
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout); ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
@ -463,11 +470,16 @@ void DialogSaveLayout::ShowExample()
break; break;
case LayoutExportFormats::SVG: case LayoutExportFormats::SVG:
case LayoutExportFormats::PDF: case LayoutExportFormats::PDF:
case LayoutExportFormats::PNG:
case LayoutExportFormats::PS: case LayoutExportFormats::PS:
case LayoutExportFormats::EPS: case LayoutExportFormats::EPS:
case LayoutExportFormats::PNG:
case LayoutExportFormats::TIF: case LayoutExportFormats::TIF:
ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout); ui->checkBoxTextAsPaths->setVisible(true);
if (settings->GetSingleLineFonts() || settings->GetSingleStrokeOutlineFont())
{
ui->checkBoxTextAsPaths->setDisabled(true);
ui->checkBoxTextAsPaths->setChecked(true);
}
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout); ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
@ -481,7 +493,12 @@ void DialogSaveLayout::ShowExample()
case LayoutExportFormats::DXF_AC1024_Flat: case LayoutExportFormats::DXF_AC1024_Flat:
case LayoutExportFormats::DXF_AC1027_Flat: case LayoutExportFormats::DXF_AC1027_Flat:
ui->checkBoxBinaryDXF->setVisible(true); ui->checkBoxBinaryDXF->setVisible(true);
ui->checkBoxTextAsPaths->setVisible(m_mode != Draw::Layout); ui->checkBoxTextAsPaths->setVisible(true);
if (settings->GetSingleLineFonts() || settings->GetSingleStrokeOutlineFont())
{
ui->checkBoxTextAsPaths->setDisabled(true);
ui->checkBoxTextAsPaths->setChecked(true);
}
ui->checkBoxShowGrainline->setVisible(true); ui->checkBoxShowGrainline->setVisible(true);
ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout); ui->checkBoxTogetherWithNotches->setVisible(m_mode != Draw::Layout);
break; break;
@ -533,14 +550,7 @@ auto DialogSaveLayout::IsTextAsPaths() const -> bool
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void DialogSaveLayout::SetTextAsPaths(bool textAsPaths) void DialogSaveLayout::SetTextAsPaths(bool textAsPaths)
{ {
if (m_mode != Draw::Layout) ui->checkBoxTextAsPaths->setChecked(textAsPaths);
{
ui->checkBoxTextAsPaths->setChecked(textAsPaths);
}
else
{
ui->checkBoxTextAsPaths->setChecked(false);
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -138,7 +138,7 @@
<string>Show grainline</string> <string>Show grainline</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>false</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -4274,7 +4274,12 @@ void MainWindow::on_actionCreateManualLayout_triggered()
DialogLayoutScale layoutScale(false, this); DialogLayoutScale layoutScale(false, this);
layoutScale.SetXScale(1); layoutScale.SetXScale(1);
layoutScale.SetYScale(1); layoutScale.SetYScale(1);
layoutScale.exec(); int const res = layoutScale.exec();
if (res == QDialog::Rejected)
{
return;
}
VLayoutExporter exporter; VLayoutExporter exporter;
exporter.SetFileName(rldFile.fileName()); exporter.SetFileName(rldFile.fileName());

View File

@ -33,6 +33,7 @@
#include "../ifc/exception/vexceptionobjecterror.h" #include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/exception/vexceptionundo.h" #include "../ifc/exception/vexceptionundo.h"
#include "../ifc/exception/vexceptionwrongid.h" #include "../ifc/exception/vexceptionwrongid.h"
#include "../ifc/ifcdef.h"
#include "../ifc/xml/vpatternconverter.h" #include "../ifc/xml/vpatternconverter.h"
#include "../qmuparser/qmuparsererror.h" #include "../qmuparser/qmuparsererror.h"
#include "../qmuparser/qmutokenparser.h" #include "../qmuparser/qmutokenparser.h"
@ -43,6 +44,7 @@
#include "../vgeometry/vsplinepath.h" #include "../vgeometry/vsplinepath.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/customevents.h" #include "../vmisc/customevents.h"
#include "../vmisc/def.h"
#include "../vmisc/projectversion.h" #include "../vmisc/projectversion.h"
#include "../vmisc/vsysexits.h" #include "../vmisc/vsysexits.h"
#include "../vmisc/vvalentinasettings.h" #include "../vmisc/vvalentinasettings.h"
@ -54,11 +56,6 @@
#include "../vpatterndb/vnodedetail.h" #include "../vpatterndb/vnodedetail.h"
#include "../vpatterndb/vpiecenode.h" #include "../vpatterndb/vpiecenode.h"
#include "../vpatterndb/vpiecepath.h" #include "../vpatterndb/vpiecepath.h"
#include "../vtools/tools/vdatatool.h"
#include "../vtools/tools/vtoolseamallowance.h"
#include "../vtools/tools/vtooluniondetails.h"
#include "../vwidgets/vabstractmainwindow.h"
#include "../vtools/tools/drawTools/operation/flipping/vtoolflippingbyaxis.h" #include "../vtools/tools/drawTools/operation/flipping/vtoolflippingbyaxis.h"
#include "../vtools/tools/drawTools/operation/flipping/vtoolflippingbyline.h" #include "../vtools/tools/drawTools/operation/flipping/vtoolflippingbyline.h"
#include "../vtools/tools/drawTools/operation/vtoolmove.h" #include "../vtools/tools/drawTools/operation/vtoolmove.h"
@ -93,7 +90,6 @@
#include "../vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h" #include "../vtools/tools/drawTools/toolpoint/toolsinglepoint/vtoolpointofintersectioncurves.h"
#include "../vtools/tools/drawTools/toolpoint/toolsinglepoint/vtooltriangle.h" #include "../vtools/tools/drawTools/toolpoint/toolsinglepoint/vtooltriangle.h"
#include "../vtools/tools/drawTools/vtoolline.h" #include "../vtools/tools/drawTools/vtoolline.h"
#include "../vtools/tools/nodeDetails/vnodearc.h" #include "../vtools/tools/nodeDetails/vnodearc.h"
#include "../vtools/tools/nodeDetails/vnodeellipticalarc.h" #include "../vtools/tools/nodeDetails/vnodeellipticalarc.h"
#include "../vtools/tools/nodeDetails/vnodepoint.h" #include "../vtools/tools/nodeDetails/vnodepoint.h"
@ -102,6 +98,11 @@
#include "../vtools/tools/nodeDetails/vtoolpiecepath.h" #include "../vtools/tools/nodeDetails/vtoolpiecepath.h"
#include "../vtools/tools/nodeDetails/vtoolpin.h" #include "../vtools/tools/nodeDetails/vtoolpin.h"
#include "../vtools/tools/nodeDetails/vtoolplacelabel.h" #include "../vtools/tools/nodeDetails/vtoolplacelabel.h"
#include "../vtools/tools/vdatatool.h"
#include "../vtools/tools/vtoolseamallowance.h"
#include "../vtools/tools/vtooluniondetails.h"
#include "../vwidgets/vabstractmainwindow.h"
#include "qminmax.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
#include "../vmisc/backport/qscopeguard.h" #include "../vmisc/backport/qscopeguard.h"
@ -161,6 +162,51 @@ auto DefLabelLanguage() -> QString
} }
return def; return def;
} }
struct VPieceFoldLineData
{
quint32 p1{NULL_ID};
quint32 p2{NULL_ID};
QString heightFormula{};
QString widthFormula{};
QString centerFormula{};
bool manualHeight{false};
bool manualWidth{false};
bool manualCenter{false};
FoldLineType type{FoldLineType::TwoArrowsTextAbove};
unsigned int fontSize{defFoldLineFontSize};
bool italic{false};
bool bold{false};
QString label{};
int alignment{Qt::AlignHCenter};
};
//---------------------------------------------------------------------------------------------------------------------
auto ParsePieceMirrorLine(const QDomElement &domElement) -> VPieceFoldLineData
{
VPieceFoldLineData data;
data.p1 = VDomDocument::GetParametrUInt(domElement, VAbstractPattern::AttrMirrorLineP1, NULL_ID_STR);
data.p2 = VDomDocument::GetParametrUInt(domElement, VAbstractPattern::AttrMirrorLineP2, NULL_ID_STR);
data.heightFormula = VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrFoldLineHeightFormula);
data.widthFormula = VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrFoldLineWidthFormula);
data.centerFormula = VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrFoldLineCenterFormula);
data.manualHeight = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrFoldLineManualHeight, falseStr);
data.manualWidth = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrFoldLineManualWidth, falseStr);
data.manualCenter = VDomDocument::GetParametrBool(domElement, VAbstractPattern::AttrFoldLineManualCenter, falseStr);
data.type = StringToFoldLineType(VDomDocument::GetParametrString(
domElement, VAbstractPattern::AttrFoldLineType, FoldLineTypeToString(FoldLineType::TwoArrowsTextAbove)));
data.fontSize = qMax(static_cast<unsigned int>(VCommonSettings::MinPieceLabelFontPointSize()),
VDomDocument::GetParametrUInt(domElement, VAbstractPattern::AttrFoldLineFontSize,
QString::number(defFoldLineFontSize)));
data.italic = VDomDocument::GetParametrBool(domElement, VDomDocument::AttrItalic, falseStr);
data.bold = VDomDocument::GetParametrBool(domElement, VDomDocument::AttrBold, falseStr);
data.label = VDomDocument::GetParametrEmptyString(domElement, VAbstractPattern::AttrFoldLineLabel);
data.alignment =
VDomDocument::GetParametrInt(domElement, VDomDocument::AttrAlignment, QString::number(Qt::AlignHCenter));
return data;
}
} // anonymous namespace } // anonymous namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -956,6 +1002,7 @@ void VPattern::ParseDetailElement(QDomElement &domElement, const Document &parse
initData.detail.SetHideMainPath( initData.detail.SetHideMainPath(
GetParametrBool(domElement, VToolSeamAllowance::AttrHideMainPath, GetParametrBool(domElement, VToolSeamAllowance::AttrHideMainPath,
QString().setNum(VAbstractValApplication::VApp()->ValentinaSettings()->IsHideMainPath()))); QString().setNum(VAbstractValApplication::VApp()->ValentinaSettings()->IsHideMainPath())));
initData.detail.SetShowFullPiece(GetParametrBool(domElement, VToolSeamAllowance::AttrShowFullPiece, trueStr));
initData.detail.SetSeamAllowanceBuiltIn( initData.detail.SetSeamAllowanceBuiltIn(
GetParametrBool(domElement, VToolSeamAllowance::AttrSeamAllowanceBuiltIn, falseStr)); GetParametrBool(domElement, VToolSeamAllowance::AttrSeamAllowanceBuiltIn, falseStr));
initData.detail.SetForbidFlipping(GetParametrBool( initData.detail.SetForbidFlipping(GetParametrBool(
@ -1009,9 +1056,15 @@ void VPattern::ParseDetailInternals(const QDomElement &domElement, VPiece &detai
{ {
const uint version = GetParametrUInt(domElement, AttrVersion, QChar('1')); const uint version = GetParametrUInt(domElement, AttrVersion, QChar('1'));
const QStringList tags = QStringList() << TagNodes << TagData << TagPatternInfo << TagGrainline const QStringList tags{TagNodes,
<< VToolSeamAllowance::TagCSA << VToolSeamAllowance::TagIPaths TagData,
<< VToolSeamAllowance::TagPins << VToolSeamAllowance::TagPlaceLabels; TagPatternInfo,
TagGrainline,
VToolSeamAllowance::TagCSA,
VToolSeamAllowance::TagIPaths,
VToolSeamAllowance::TagPins,
VToolSeamAllowance::TagPlaceLabels,
VToolSeamAllowance::TagMirrorLine};
QFuture<QVector<VPieceNode>> futurePathV1; QFuture<QVector<VPieceNode>> futurePathV1;
QFuture<VPiecePath> futurePathV2; QFuture<VPiecePath> futurePathV2;
@ -1022,6 +1075,7 @@ void VPattern::ParseDetailInternals(const QDomElement &domElement, VPiece &detai
QFuture<QVector<quint32>> futureIPaths; QFuture<QVector<quint32>> futureIPaths;
QFuture<QVector<quint32>> futurePins; QFuture<QVector<quint32>> futurePins;
QFuture<QVector<quint32>> futurePlaceLabels; QFuture<QVector<quint32>> futurePlaceLabels;
QFuture<VPieceFoldLineData> futureMirrorLine;
const QDomNodeList nodeList = domElement.childNodes(); const QDomNodeList nodeList = domElement.childNodes();
for (qint32 i = 0; i < nodeList.size(); ++i) for (qint32 i = 0; i < nodeList.size(); ++i)
@ -1076,6 +1130,9 @@ void VPattern::ParseDetailInternals(const QDomElement &domElement, VPiece &detai
case 7: // VToolSeamAllowance::TagPlaceLabels case 7: // VToolSeamAllowance::TagPlaceLabels
futurePlaceLabels = QtConcurrent::run(&VPattern::ParsePiecePointRecords, element); futurePlaceLabels = QtConcurrent::run(&VPattern::ParsePiecePointRecords, element);
break; break;
case 8: // VToolSeamAllowance::TagMirrorLine
futureMirrorLine = QtConcurrent::run(&ParsePieceMirrorLine, element);
break;
default: default:
break; break;
} }
@ -1125,6 +1182,25 @@ void VPattern::ParseDetailInternals(const QDomElement &domElement, VPiece &detai
{ {
detail.SetPlaceLabels(futurePlaceLabels.result()); detail.SetPlaceLabels(futurePlaceLabels.result());
} }
if (not futureMirrorLine.isCanceled())
{
VPieceFoldLineData const data = futureMirrorLine.result();
detail.SetMirrorLineStartPoint(data.p1);
detail.SetMirrorLineEndPoint(data.p2);
detail.SetManualFoldHeight(data.manualHeight);
detail.SetManualFoldWidth(data.manualWidth);
detail.SetManualFoldCenter(data.manualCenter);
detail.SetFormulaFoldHeight(data.heightFormula);
detail.SetFormulaFoldWidth(data.widthFormula);
detail.SetFormulaFoldCenter(data.centerFormula);
detail.SetFoldLineType(data.type);
detail.SetFoldLineSvgFontSize(data.fontSize);
detail.SetFoldLineLabelFontItalic(data.italic);
detail.SetFoldLineLabelFontBold(data.bold);
detail.SetFoldLineLabel(data.label);
detail.SetFoldLineLabelAlignment(data.alignment);
}
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -2042,6 +2118,8 @@ void VPattern::ParsePlaceLabel(QDomElement &domElement, const Document &parse)
initData.type = static_cast<PlaceLabelType>(GetParametrUInt(domElement, AttrPlaceLabelType, QChar('0'))); initData.type = static_cast<PlaceLabelType>(GetParametrUInt(domElement, AttrPlaceLabelType, QChar('0')));
initData.notMirrored = GetParametrBool(domElement, AttrNotMirrored, falseStr);
VToolPlaceLabel::Create(initData); VToolPlaceLabel::Create(initData);
// Rewrite attribute formula. Need for situation when we have wrong formula. // Rewrite attribute formula. Need for situation when we have wrong formula.
@ -4096,6 +4174,7 @@ void VPattern::ParsePathElement(VMainGraphicsScene *scene, QDomElement &domEleme
initData.path.SetFirstToCuttingContour(GetParametrBool(domElement, AttrFirstToContour, falseStr)); initData.path.SetFirstToCuttingContour(GetParametrBool(domElement, AttrFirstToContour, falseStr));
initData.path.SetLastToCuttingContour(GetParametrBool(domElement, AttrLastToContour, falseStr)); initData.path.SetLastToCuttingContour(GetParametrBool(domElement, AttrLastToContour, falseStr));
initData.path.SetVisibilityTrigger(GetParametrString(domElement, AttrVisible, QChar('1'))); initData.path.SetVisibilityTrigger(GetParametrString(domElement, AttrVisible, QChar('1')));
initData.path.SetNotMirrored(GetParametrBool(domElement, AttrNotMirrored, falseStr));
} }
VToolPiecePath::Create(initData); VToolPiecePath::Create(initData);

View File

@ -149,6 +149,7 @@ const QString AttrCurve2Alias1 = QStringLiteral("curve2Alias1");
const QString AttrCurve2Alias2 = QStringLiteral("curve2Alias2"); const QString AttrCurve2Alias2 = QStringLiteral("curve2Alias2");
const QString AttrLayoutVersion = QStringLiteral("version"); const QString AttrLayoutVersion = QStringLiteral("version");
const QString AttrKMVersion = QStringLiteral("version"); const QString AttrKMVersion = QStringLiteral("version");
const QString AttrNotMirrored = QStringLiteral("notMirrored");
const QString TypeLineDefault = QStringLiteral("default"); const QString TypeLineDefault = QStringLiteral("default");
const QString TypeLineNone = QStringLiteral("none"); const QString TypeLineNone = QStringLiteral("none");

View File

@ -166,6 +166,7 @@ extern const QString AttrCurve2Alias1;
extern const QString AttrCurve2Alias2; extern const QString AttrCurve2Alias2;
extern const QString AttrLayoutVersion; extern const QString AttrLayoutVersion;
extern const QString AttrKMVersion; extern const QString AttrKMVersion;
extern const QString AttrNotMirrored;
extern const QString TypeLineDefault; extern const QString TypeLineDefault;
extern const QString TypeLineNone; extern const QString TypeLineNone;

View File

@ -69,6 +69,7 @@
<file>schema/pattern/v0.9.1.xsd</file> <file>schema/pattern/v0.9.1.xsd</file>
<file>schema/pattern/v0.9.2.xsd</file> <file>schema/pattern/v0.9.2.xsd</file>
<file>schema/pattern/v0.9.3.xsd</file> <file>schema/pattern/v0.9.3.xsd</file>
<file>schema/pattern/v0.9.4.xsd</file>
<file>schema/multisize_measurements/v0.3.0.xsd</file> <file>schema/multisize_measurements/v0.3.0.xsd</file>
<file>schema/multisize_measurements/v0.4.0.xsd</file> <file>schema/multisize_measurements/v0.4.0.xsd</file>
<file>schema/multisize_measurements/v0.4.1.xsd</file> <file>schema/multisize_measurements/v0.4.1.xsd</file>
@ -104,6 +105,7 @@
<file>schema/layout/v0.1.5.xsd</file> <file>schema/layout/v0.1.5.xsd</file>
<file>schema/layout/v0.1.6.xsd</file> <file>schema/layout/v0.1.6.xsd</file>
<file>schema/layout/v0.1.7.xsd</file> <file>schema/layout/v0.1.7.xsd</file>
<file>schema/layout/v0.1.8.xsd</file>
<file>schema/known_measurements/v1.0.0.xsd</file> <file>schema/known_measurements/v1.0.0.xsd</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,646 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="layout">
<xs:complexType>
<xs:sequence>
<xs:element name="properties">
<xs:complexType>
<xs:sequence>
<xs:element type="units" name="unit"/>
<xs:element type="xs:string" name="title"/>
<xs:element type="xs:string" name="description"/>
<xs:element name="control">
<xs:complexType>
<xs:attribute type="xs:boolean" name="warningSuperposition"/>
<xs:attribute type="xs:boolean" name="warningOutOfBound"/>
<xs:attribute type="xs:boolean" name="stickyEdges"/>
<xs:attribute type="xs:boolean" name="followGrainline"/>
<xs:attribute type="xs:boolean" name="boundaryTogetherWithNotches"/>
<xs:attribute type="xs:float" name="piecesGap"/>
<xs:attribute type="xs:boolean" name="cutOnFold"/>
</xs:complexType>
</xs:element>
<xs:element name="tiles">
<xs:complexType>
<xs:sequence>
<xs:element name="size">
<xs:complexType>
<xs:attribute type="xs:float" name="width" use="required"/>
<xs:attribute type="xs:float" name="length" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="margin">
<xs:complexType>
<xs:attribute type="xs:float" name="top"/>
<xs:attribute type="xs:float" name="right"/>
<xs:attribute type="xs:float" name="bottom"/>
<xs:attribute type="xs:float" name="left"/>
<xs:attribute type="xs:boolean" name="ignoreMargins"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="visible"/>
<xs:attribute type="xs:string" name="matchingMarks"/>
<xs:attribute type="xs:boolean" name="printScheme"/>
<xs:attribute type="xs:boolean" name="tileNumber"/>
</xs:complexType>
</xs:element>
<xs:element name="scale">
<xs:complexType>
<xs:attribute type="LayoutScale" name="xScale"/>
<xs:attribute type="LayoutScale" name="yScale"/>
</xs:complexType>
</xs:element>
<xs:element name="watermark">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="showPreview" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="unplacedPieces">
<xs:complexType>
<xs:sequence>
<xs:element name="piece" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="seamLine">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="seamAllowance">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="LinePathOrEmpty">
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
<xs:attribute type="ArrowDirection" name="arrowDirection" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="notches">
<xs:complexType>
<xs:sequence>
<xs:element name="notch" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
<xs:attribute type="NotchType" name="type" use="optional"/>
<xs:attribute type="LinePath" name="baseLine" use="optional"/>
<xs:attribute type="LinesPath" name="path" use="optional"/>
<xs:attribute type="xs:boolean" name="clockwiseOpening" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="internalPaths">
<xs:complexType>
<xs:sequence>
<xs:element name="internalPath" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="2" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="cut" use="optional"/>
<xs:attribute type="CurvePenStyle" name="penStyle" use="optional"/>
<xs:attribute type="xs:boolean" name="notMirrored" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="markers">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="marker" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:attribute type="Transformation" name="transform" use="required"/>
<xs:attribute type="MarkerType" name="type" use="required"/>
<xs:attribute type="PointPath" name="center" use="required"/>
<xs:attribute type="RectPath" name="box" use="required"/>
<xs:attribute type="xs:boolean" name="notMirrored" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="labels">
<xs:complexType>
<xs:sequence>
<xs:element name="pieceLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
<xs:attribute type="xs:string" name="svgFont"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="shape" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
<xs:attribute type="xs:string" name="svgFont"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="shape" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="mirrorLine" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element type="LinePathOrEmpty" name="seamLine"/>
<xs:element type="LinePathOrEmpty" name="seamAllowance"/>
</xs:sequence>
<xs:attribute name="type" type="foldLineType" use="optional"/>
<xs:attribute name="height" type="xs:double" use="optional"/>
<xs:attribute name="width" type="xs:double" use="optional"/>
<xs:attribute name="center" type="xs:double" use="optional"/>
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute type="xs:string" name="font" use="optional"/>
<xs:attribute type="xs:string" name="svgFont" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="uid" type="uuid" use="required"/>
<xs:attribute type="xs:string" name="name"/>
<xs:attribute type="xs:boolean" name="verticallyFlipped"/>
<xs:attribute type="xs:boolean" name="horizontallyFlipped"/>
<xs:attribute type="xs:boolean" name="forbidFlipping"/>
<xs:attribute type="xs:boolean" name="forceFlipping"/>
<xs:attribute type="xs:boolean" name="followGrainline"/>
<xs:attribute type="xs:boolean" name="sewLineOnDrawing"/>
<xs:attribute type="Transformation" name="transform"/>
<xs:attribute type="xs:string" name="gradationLabel"/>
<xs:attribute type="xs:unsignedInt" name="copyNumber"/>
<xs:attribute type="xs:boolean" name="showSeamline"/>
<xs:attribute type="xs:float" name="xScale"/>
<xs:attribute type="xs:float" name="yScale"/>
<xs:attribute type="xs:boolean" name="showFullPiece"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sheets">
<xs:complexType>
<xs:sequence>
<xs:element name="sheet" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element name="size">
<xs:complexType>
<xs:attribute type="xs:float" name="width" use="required"/>
<xs:attribute type="xs:float" name="length" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="margin">
<xs:complexType>
<xs:attribute type="xs:float" name="top"/>
<xs:attribute type="xs:float" name="right"/>
<xs:attribute type="xs:float" name="bottom"/>
<xs:attribute type="xs:float" name="left"/>
<xs:attribute type="xs:boolean" name="ignoreMargins"/>
</xs:complexType>
</xs:element>
<xs:element name="pieces">
<xs:complexType>
<xs:sequence>
<xs:element name="piece" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="seamLine">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="3" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="seamAllowance">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="grainline">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="LinePathOrEmpty">
<xs:attribute type="xs:boolean" name="enabled" use="optional"/>
<xs:attribute type="ArrowDirection" name="arrowDirection" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="notches">
<xs:complexType>
<xs:sequence>
<xs:element name="notch" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:boolean" name="builtIn" use="optional"/>
<xs:attribute type="NotchType" name="type" use="optional"/>
<xs:attribute type="LinePath" name="baseLine" use="optional"/>
<xs:attribute type="LinesPath" name="path" use="optional"/>
<xs:attribute type="xs:boolean" name="clockwiseOpening" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="internalPaths">
<xs:complexType>
<xs:sequence>
<xs:element name="internalPath" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="2" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute type="xs:double" name="x" use="required"/>
<xs:attribute type="xs:double" name="y" use="required"/>
<xs:attribute type="xs:boolean" name="turnPoint" use="optional"/>
<xs:attribute type="xs:boolean" name="curvePoint" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:boolean" name="cut" use="optional"/>
<xs:attribute type="CurvePenStyle" name="penStyle" use="optional"/>
<xs:attribute type="xs:boolean" name="notMirrored" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="markers">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="marker" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:attribute type="Transformation" name="transform" use="required"/>
<xs:attribute type="MarkerType" name="type" use="required"/>
<xs:attribute type="PointPath" name="center" use="required"/>
<xs:attribute type="RectPath" name="box" use="required"/>
<xs:attribute type="xs:boolean" name="notMirrored" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="labels">
<xs:complexType>
<xs:sequence>
<xs:element name="pieceLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
<xs:attribute type="xs:string" name="svgFont"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="PathNotEmpty" name="shape" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="patternLabel" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="lines">
<xs:complexType>
<xs:sequence>
<xs:element name="line" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
<xs:attribute type="xs:unsignedInt" name="fontSize" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="xs:string" name="font"/>
<xs:attribute type="xs:string" name="svgFont"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="PathNotEmpty" name="shape" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="mirrorLine" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element type="LinePathOrEmpty" name="seamLine"/>
<xs:element type="LinePathOrEmpty" name="seamAllowance"/>
</xs:sequence>
<xs:attribute name="type" type="foldLineType" use="optional"/>
<xs:attribute name="height" type="xs:double" use="optional"/>
<xs:attribute name="width" type="xs:double" use="optional"/>
<xs:attribute name="center" type="xs:double" use="optional"/>
<xs:attribute type="xs:boolean" name="bold" use="optional"/>
<xs:attribute type="xs:boolean" name="italic" use="optional"/>
<xs:attribute type="AlignmentType" name="alignment" use="optional"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute type="xs:string" name="font" use="optional"/>
<xs:attribute type="xs:string" name="svgFont" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="uid" type="uuid" use="required"/>
<xs:attribute type="xs:string" name="name"/>
<xs:attribute type="xs:boolean" name="verticallyFlipped"/>
<xs:attribute type="xs:boolean" name="horizontallyFlipped"/>
<xs:attribute type="xs:boolean" name="forbidFlipping"/>
<xs:attribute type="xs:boolean" name="forceFlipping"/>
<xs:attribute type="xs:boolean" name="followGrainline"/>
<xs:attribute type="xs:boolean" name="sewLineOnDrawing"/>
<xs:attribute type="Transformation" name="transform"/>
<xs:attribute type="xs:string" name="gradationLabel"/>
<xs:attribute type="xs:unsignedInt" name="copyNumber"/>
<xs:attribute type="xs:boolean" name="showSeamline"/>
<xs:attribute type="xs:float" name="xScale"/>
<xs:attribute type="xs:float" name="yScale"/>
<xs:attribute type="xs:float" name="zValue"/>
<xs:attribute type="xs:boolean" name="showFullPiece"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="GrainlineType" name="grainlineType"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute type="formatVersion" name="version" use="required"/>
</xs:complexType>
</xs:element>
<!--Types-->
<xs:simpleType name="formatVersion">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="units">
<xs:restriction base="xs:string">
<xs:enumeration value="mm"/>
<xs:enumeration value="cm"/>
<xs:enumeration value="inch"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="uuid">
<xs:restriction base="xs:string">
<xs:pattern value="|\{[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}\}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ArrowDirection">
<xs:restriction base="xs:string">
<xs:enumeration value="oneWayUp"/>
<xs:enumeration value="oneWayDown"/>
<xs:enumeration value="twoWaysUpDown"/>
<xs:enumeration value="fourWays"/>
<xs:enumeration value="twoWaysUpLeft"/>
<xs:enumeration value="twoWaysUpRight"/>
<xs:enumeration value="twoWaysDownLeft"/>
<xs:enumeration value="twoWaysDownRight"/>
<xs:enumeration value="threeWaysUpDownLeft"/>
<xs:enumeration value="threeWaysUpDownRight"/>
<xs:enumeration value="threeWaysUpLeftRight"/>
<xs:enumeration value="threeWaysDownLeftRight"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NotchType">
<xs:restriction base="xs:unsignedInt">
<!--OneLine-->
<xs:enumeration value="0"/>
<!--TwoLines-->
<xs:enumeration value="1"/>
<!--ThreeLines-->
<xs:enumeration value="2"/>
<!--TMark-->
<xs:enumeration value="3"/>
<!--VMark-->
<xs:enumeration value="4"/>
<!--VMark2-->
<xs:enumeration value="5"/>
<!--UMark-->
<xs:enumeration value="6"/>
<!--BoxMark-->
<xs:enumeration value="7"/>
<!--CheckMark-->
<xs:enumeration value="8"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CurvePenStyle">
<xs:restriction base="xs:string">
<xs:enumeration value="hair"/>
<xs:enumeration value="dashLine"/>
<xs:enumeration value="dotLine"/>
<xs:enumeration value="dashDotLine"/>
<xs:enumeration value="dashDotDotLine"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MarkerType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/><!--Segment-->
<xs:enumeration value="1"/><!--Rectangle-->
<xs:enumeration value="2"/><!--Cross-->
<xs:enumeration value="3"/><!--Tshaped-->
<xs:enumeration value="4"/><!--Doubletree-->
<xs:enumeration value="5"/><!--Corner-->
<xs:enumeration value="6"/><!--Triangle-->
<xs:enumeration value="7"/><!--Hshaped-->
<xs:enumeration value="8"/><!--Button-->
<xs:enumeration value="9"/><!--Circle-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AlignmentType">
<xs:restriction base="xs:unsignedInt">
<xs:enumeration value="0"/><!--default (no aligns)-->
<xs:enumeration value="1"/><!--aligns with the left edge-->
<xs:enumeration value="2"/><!--aligns with the right edge-->
<xs:enumeration value="4"/><!--Centers horizontally in the available space-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Transformation">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){8,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PathNotEmpty">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\s){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PathOrEmpty">
<xs:restriction base="xs:string">
<xs:pattern value="|([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\s){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LinePathOrEmpty">
<xs:restriction base="xs:string">
<xs:pattern value="|[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LinePath">
<xs:restriction base="xs:string">
<xs:pattern value="[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LinesPath">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?\*){0,}[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?;[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PointPath">
<xs:restriction base="xs:string">
<xs:pattern value="[-+]?\d+\.?\d*([eE][-+]?\d+)?,[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RectPath">
<xs:restriction base="xs:string">
<xs:pattern value="([-+]?\d+\.?\d*([eE][-+]?\d+)?;){3,}[-+]?\d+\.?\d*([eE][-+]?\d+)?"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="GrainlineType">
<xs:restriction base="xs:string">
<xs:enumeration value="horizontal"/>
<xs:enumeration value="vertical"/>
<xs:enumeration value="notFixed"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LayoutScale">
<xs:restriction base="xs:float">
<xs:minInclusive value="0.01"/>
<xs:maxInclusive value="3"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="foldLineType">
<xs:restriction base="xs:string">
<xs:enumeration value="2ArrowsTextAbove"/><!--Same as default-->
<xs:enumeration value="2ArrowsTextUnder"/>
<xs:enumeration value="2Arrows"/>
<xs:enumeration value="text"/>
<xs:enumeration value="3dots"/>
<xs:enumeration value="3X"/>
<xs:enumeration value="none"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

File diff suppressed because it is too large Load Diff

View File

@ -155,6 +155,17 @@ const QString VAbstractPattern::AttrImageId = QStringLiteral("imageId");
const QString VAbstractPattern::AttrDimensionA = QStringLiteral("dimensionA"); const QString VAbstractPattern::AttrDimensionA = QStringLiteral("dimensionA");
const QString VAbstractPattern::AttrDimensionB = QStringLiteral("dimensionB"); const QString VAbstractPattern::AttrDimensionB = QStringLiteral("dimensionB");
const QString VAbstractPattern::AttrDimensionC = QStringLiteral("dimensionC"); const QString VAbstractPattern::AttrDimensionC = QStringLiteral("dimensionC");
const QString VAbstractPattern::AttrMirrorLineP1 = QStringLiteral("p1");
const QString VAbstractPattern::AttrMirrorLineP2 = QStringLiteral("p2");
const QString VAbstractPattern::AttrFoldLineHeightFormula = QStringLiteral("height");
const QString VAbstractPattern::AttrFoldLineWidthFormula = QStringLiteral("width");
const QString VAbstractPattern::AttrFoldLineCenterFormula = QStringLiteral("center");
const QString VAbstractPattern::AttrFoldLineManualHeight = QStringLiteral("manualHeight");
const QString VAbstractPattern::AttrFoldLineManualWidth = QStringLiteral("manualWidth");
const QString VAbstractPattern::AttrFoldLineManualCenter = QStringLiteral("manualCenter");
const QString VAbstractPattern::AttrFoldLineType = QStringLiteral("type");
const QString VAbstractPattern::AttrFoldLineFontSize = QStringLiteral("fontSize");
const QString VAbstractPattern::AttrFoldLineLabel = QStringLiteral("label");
const QString VAbstractPattern::AttrContentType = QStringLiteral("contentType"); const QString VAbstractPattern::AttrContentType = QStringLiteral("contentType");
@ -764,8 +775,9 @@ auto VAbstractPattern::ParsePieceInternalPaths(const QDomElement &domElement) ->
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractPattern::ParsePiecePointRecords(const QDomElement &domElement) -> QVector<quint32> auto VAbstractPattern::ParsePiecePointRecords(const QDomElement &domElement) -> QVector<quint32>
{ {
QVector<quint32> records;
const QDomNodeList nodeList = domElement.childNodes(); const QDomNodeList nodeList = domElement.childNodes();
QVector<quint32> records;
records.reserve(nodeList.size());
for (qint32 i = 0; i < nodeList.size(); ++i) for (qint32 i = 0; i < nodeList.size(); ++i)
{ {
const QDomElement element = nodeList.at(i).toElement(); const QDomElement element = nodeList.at(i).toElement();

View File

@ -382,6 +382,17 @@ public:
static const QString AttrDimensionA; static const QString AttrDimensionA;
static const QString AttrDimensionB; static const QString AttrDimensionB;
static const QString AttrDimensionC; static const QString AttrDimensionC;
static const QString AttrMirrorLineP1;
static const QString AttrMirrorLineP2;
static const QString AttrFoldLineHeightFormula;
static const QString AttrFoldLineWidthFormula;
static const QString AttrFoldLineCenterFormula;
static const QString AttrFoldLineManualHeight;
static const QString AttrFoldLineManualWidth;
static const QString AttrFoldLineManualCenter;
static const QString AttrFoldLineType;
static const QString AttrFoldLineFontSize;
static const QString AttrFoldLineLabel;
static const QString AttrContentType; static const QString AttrContentType;

View File

@ -45,8 +45,8 @@ using namespace Qt::Literals::StringLiterals;
*/ */
const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0"); const QString VLayoutConverter::LayoutMinVerStr = QStringLiteral("0.1.0");
const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.7"); const QString VLayoutConverter::LayoutMaxVerStr = QStringLiteral("0.1.8");
const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.7.xsd"); const QString VLayoutConverter::CurrentSchema = QStringLiteral("://schema/layout/v0.1.8.xsd");
// VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! // VLayoutConverter::LayoutMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
// VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! // VLayoutConverter::LayoutMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
@ -151,7 +151,8 @@ auto VLayoutConverter::XSDSchemas() -> QHash<unsigned int, QString>
std::make_pair(FormatVersion(0, 1, 4), QStringLiteral("://schema/layout/v0.1.4.xsd")), std::make_pair(FormatVersion(0, 1, 4), QStringLiteral("://schema/layout/v0.1.4.xsd")),
std::make_pair(FormatVersion(0, 1, 5), QStringLiteral("://schema/layout/v0.1.5.xsd")), std::make_pair(FormatVersion(0, 1, 5), QStringLiteral("://schema/layout/v0.1.5.xsd")),
std::make_pair(FormatVersion(0, 1, 6), QStringLiteral("://schema/layout/v0.1.6.xsd")), std::make_pair(FormatVersion(0, 1, 6), QStringLiteral("://schema/layout/v0.1.6.xsd")),
std::make_pair(FormatVersion(0, 1, 7), CurrentSchema), std::make_pair(FormatVersion(0, 1, 7), QStringLiteral("://schema/layout/v0.1.7.xsd")),
std::make_pair(FormatVersion(0, 1, 8), CurrentSchema),
}; };
return schemas; return schemas;
@ -190,9 +191,12 @@ void VLayoutConverter::ApplyPatches()
case (FormatVersion(0, 1, 5)): case (FormatVersion(0, 1, 5)):
case (FormatVersion(0, 1, 6)): case (FormatVersion(0, 1, 6)):
ToV0_1_7(); ToV0_1_7();
ValidateXML(CurrentSchema);
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case (FormatVersion(0, 1, 7)): case (FormatVersion(0, 1, 7)):
ToV0_1_8();
ValidateXML(CurrentSchema);
Q_FALLTHROUGH();
case (FormatVersion(0, 1, 8)):
break; break;
default: default:
InvalidVersion(m_ver); InvalidVersion(m_ver);
@ -431,3 +435,13 @@ void VLayoutConverter::ToV0_1_7()
SetVersion(QStringLiteral("0.1.7")); SetVersion(QStringLiteral("0.1.7"));
Save(); Save();
} }
//---------------------------------------------------------------------------------------------------------------------
void VLayoutConverter::ToV0_1_8()
{
// TODO. Delete if minimal supported version is 0.1.8
Q_STATIC_ASSERT_X(VLayoutConverter::LayoutMinVer < FormatVersion(0, 1, 8), "Time to refactor the code.");
SetVersion(QStringLiteral("0.1.8"));
Save();
}

View File

@ -47,7 +47,7 @@ public:
static const QString LayoutMaxVerStr; static const QString LayoutMaxVerStr;
static const QString CurrentSchema; static const QString CurrentSchema;
static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0); static Q_DECL_CONSTEXPR const unsigned LayoutMinVer = FormatVersion(0, 1, 0);
static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 7); static Q_DECL_CONSTEXPR const unsigned LayoutMaxVer = FormatVersion(0, 1, 8);
static auto XSDSchemas() -> QHash<unsigned, QString>; static auto XSDSchemas() -> QHash<unsigned, QString>;
@ -77,6 +77,7 @@ protected:
void ToV0_1_3(); void ToV0_1_3();
void ToV0_1_5(); void ToV0_1_5();
void ToV0_1_7(); void ToV0_1_7();
void ToV0_1_8();
private: private:
Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT Q_DISABLE_COPY_MOVE(VLayoutConverter) // NOLINT

View File

@ -38,7 +38,6 @@
#include <QLatin1String> #include <QLatin1String>
#include <QList> #include <QList>
#include <QUuid> #include <QUuid>
#include <algorithm>
#include "../exception/vexception.h" #include "../exception/vexception.h"
#include "../exception/vexceptionemptyparameter.h" #include "../exception/vexceptionemptyparameter.h"
@ -63,8 +62,8 @@ class QDomElement;
*/ */
const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.4"); // NOLINT const QString VPatternConverter::PatternMinVerStr = QStringLiteral("0.1.4"); // NOLINT
const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.9.3"); // NOLINT const QString VPatternConverter::PatternMaxVerStr = QStringLiteral("0.9.4"); // NOLINT
const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.9.3.xsd"); // NOLINT const QString VPatternConverter::CurrentSchema = QStringLiteral("://schema/pattern/v0.9.4.xsd"); // NOLINT
// VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!! // VPatternConverter::PatternMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
// VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!! // VPatternConverter::PatternMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
@ -265,7 +264,8 @@ auto VPatternConverter::XSDSchemas() -> QHash<unsigned int, QString>
std::make_pair(FormatVersion(0, 9, 0), QStringLiteral("://schema/pattern/v0.9.0.xsd")), std::make_pair(FormatVersion(0, 9, 0), QStringLiteral("://schema/pattern/v0.9.0.xsd")),
std::make_pair(FormatVersion(0, 9, 1), QStringLiteral("://schema/pattern/v0.9.1.xsd")), std::make_pair(FormatVersion(0, 9, 1), QStringLiteral("://schema/pattern/v0.9.1.xsd")),
std::make_pair(FormatVersion(0, 9, 2), QStringLiteral("://schema/pattern/v0.9.2.xsd")), std::make_pair(FormatVersion(0, 9, 2), QStringLiteral("://schema/pattern/v0.9.2.xsd")),
std::make_pair(FormatVersion(0, 9, 3), CurrentSchema)}; std::make_pair(FormatVersion(0, 9, 3), QStringLiteral("://schema/pattern/v0.9.3.xsd")),
std::make_pair(FormatVersion(0, 9, 4), CurrentSchema)};
return schemas; return schemas;
} }
@ -385,10 +385,11 @@ void VPatternConverter::ApplyPatches()
ToV0_9_2(); ToV0_9_2();
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case (FormatVersion(0, 9, 2)): case (FormatVersion(0, 9, 2)):
ToV0_9_3(); case (FormatVersion(0, 9, 3)):
ToV0_9_4();
ValidateXML(CurrentSchema); ValidateXML(CurrentSchema);
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case (FormatVersion(0, 9, 3)): case (FormatVersion(0, 9, 4)):
break; break;
default: default:
InvalidVersion(m_ver); InvalidVersion(m_ver);
@ -406,7 +407,7 @@ void VPatternConverter::DowngradeToCurrentMaxVersion()
auto VPatternConverter::IsReadOnly() const -> bool auto VPatternConverter::IsReadOnly() const -> bool
{ {
// Check if attribute readOnly was not changed in file format // Check if attribute readOnly was not changed in file format
Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == FormatVersion(0, 9, 3), "Check attribute readOnly."); Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == FormatVersion(0, 9, 4), "Check attribute readOnly.");
// Possibly in future attribute readOnly will change position etc. // Possibly in future attribute readOnly will change position etc.
// For now position is the same for all supported format versions. // For now position is the same for all supported format versions.
@ -582,12 +583,12 @@ void VPatternConverter::ToV0_9_2()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ToV0_9_3() void VPatternConverter::ToV0_9_4()
{ {
// TODO. Delete if minimal supported version is 0.9.3 // TODO. Delete if minimal supported version is 0.9.4
Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < FormatVersion(0, 9, 3), "Time to refactor the code."); Q_STATIC_ASSERT_X(VPatternConverter::PatternMinVer < FormatVersion(0, 9, 4), "Time to refactor the code.");
SetVersion(QStringLiteral("0.9.3")); SetVersion(QStringLiteral("0.9.4"));
Save(); Save();
} }

View File

@ -54,7 +54,7 @@ public:
static const QString PatternMaxVerStr; static const QString PatternMaxVerStr;
static const QString CurrentSchema; static const QString CurrentSchema;
static Q_DECL_CONSTEXPR const unsigned PatternMinVer = FormatVersion(0, 1, 4); static Q_DECL_CONSTEXPR const unsigned PatternMinVer = FormatVersion(0, 1, 4);
static Q_DECL_CONSTEXPR const unsigned PatternMaxVer = FormatVersion(0, 9, 3); static Q_DECL_CONSTEXPR const unsigned PatternMaxVer = FormatVersion(0, 9, 4);
static auto XSDSchemas() -> QHash<unsigned, QString>; static auto XSDSchemas() -> QHash<unsigned, QString>;
@ -91,7 +91,7 @@ private:
void ToV0_9_0(); void ToV0_9_0();
void ToV0_9_1(); void ToV0_9_1();
void ToV0_9_2(); void ToV0_9_2();
void ToV0_9_3(); void ToV0_9_4();
void TagUnitToV0_2_0(); void TagUnitToV0_2_0();
void TagIncrementToV0_2_0(); void TagIncrementToV0_2_0();

View File

@ -220,6 +220,25 @@ void dx_iface::InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits
} }
} }
auto dx_iface::QtPenStyleToString(Qt::PenStyle style) -> UTF8STRING
{
switch (style)
{
case Qt::DashLine:
return "DASHED";
case Qt::DotLine:
return "DOT";
case Qt::DashDotLine:
return "DASHDOT2";
case Qt::DashDotDotLine:
return "DIVIDE2";
case Qt::NoPen:
case Qt::SolidLine:
default:
return "CONTINUOUS";
}
}
void dx_iface::AddQtLTypes() void dx_iface::AddQtLTypes()
{ {
DRW_LType ltype; DRW_LType ltype;

View File

@ -12,106 +12,117 @@
#ifndef DX_IFACE_H #ifndef DX_IFACE_H
#define DX_IFACE_H #define DX_IFACE_H
#include "dxfdef.h"
#include "libdxfrw/drw_interface.h" #include "libdxfrw/drw_interface.h"
#include "libdxfrw/libdxfrw.h" #include "libdxfrw/libdxfrw.h"
#include "dxfdef.h"
#include <Qt>
class QFont; class QFont;
//class to store image data and path from DRW_ImageDef // class to store image data and path from DRW_ImageDef
class dx_ifaceImg : public DRW_Image { class dx_ifaceImg : public DRW_Image
{
public: public:
dx_ifaceImg() dx_ifaceImg()
: path() : path()
{} {
}
explicit dx_ifaceImg(const DRW_Image& p) explicit dx_ifaceImg(const DRW_Image &p)
: DRW_Image(p), : DRW_Image(p),
path() path()
{} {
}
virtual ~dx_ifaceImg() = default; virtual ~dx_ifaceImg() = default;
std::string path; //stores the image path std::string path; // stores the image path
}; };
//container class to store entites. // container class to store entites.
class dx_ifaceBlock final : public DRW_Block { class dx_ifaceBlock final : public DRW_Block
{
public: public:
dx_ifaceBlock() dx_ifaceBlock()
: ent() : ent()
{} {
}
explicit dx_ifaceBlock(const DRW_Block& p) explicit dx_ifaceBlock(const DRW_Block &p)
: DRW_Block(p), : DRW_Block(p),
ent() ent()
{} {
}
virtual ~dx_ifaceBlock(){ virtual ~dx_ifaceBlock()
for (std::list<DRW_Entity*>::const_iterator it=ent.begin(); it!=ent.end(); ++it) {
for (std::list<DRW_Entity *>::const_iterator it = ent.begin(); it != ent.end(); ++it)
delete *it; delete *it;
} }
std::list<DRW_Entity*>ent; //stores the entities list std::list<DRW_Entity *> ent; // stores the entities list
}; };
// container class to store full dxf data.
//container class to store full dxf data. class dx_data
class dx_data { {
public: public:
dx_data() dx_data()
: headerC(), : headerC(),
lineTypes(), lineTypes(),
layers(), layers(),
dimStyles(), dimStyles(),
VPorts(), VPorts(),
textStyles(), textStyles(),
appIds(), appIds(),
blocks(), blocks(),
images(), images(),
mBlock(new dx_ifaceBlock()) mBlock(new dx_ifaceBlock())
{} {
}
~dx_data(){ ~dx_data()
//cleanup, {
for (std::list<dx_ifaceBlock*>::const_iterator it=blocks.begin(); it!=blocks.end(); ++it) // cleanup,
for (std::list<dx_ifaceBlock *>::const_iterator it = blocks.begin(); it != blocks.end(); ++it)
delete *it; delete *it;
delete mBlock; delete mBlock;
} }
DRW_Header headerC; //stores a copy of the header vars DRW_Header headerC; // stores a copy of the header vars
std::list<DRW_LType>lineTypes; //stores a copy of all line types std::list<DRW_LType> lineTypes; // stores a copy of all line types
std::list<DRW_Layer>layers; //stores a copy of all layers std::list<DRW_Layer> layers; // stores a copy of all layers
std::list<DRW_Dimstyle>dimStyles; //stores a copy of all dimension styles std::list<DRW_Dimstyle> dimStyles; // stores a copy of all dimension styles
std::list<DRW_Vport>VPorts; //stores a copy of all vports std::list<DRW_Vport> VPorts; // stores a copy of all vports
std::list<DRW_Textstyle>textStyles; //stores a copy of all text styles std::list<DRW_Textstyle> textStyles; // stores a copy of all text styles
std::list<DRW_AppId>appIds; //stores a copy of all line types std::list<DRW_AppId> appIds; // stores a copy of all line types
std::list<dx_ifaceBlock*>blocks; //stores a copy of all blocks and the entities in it std::list<dx_ifaceBlock *> blocks; // stores a copy of all blocks and the entities in it
std::list<dx_ifaceImg*>images; //temporary list to find images for link with DRW_ImageDef. Do not delete it!! std::list<dx_ifaceImg *> images; // temporary list to find images for link with DRW_ImageDef. Do not delete it!!
dx_ifaceBlock *mBlock; // container to store model entities
dx_ifaceBlock* mBlock; //container to store model entities
private: private:
Q_DISABLE_COPY_MOVE(dx_data) // NOLINT Q_DISABLE_COPY_MOVE(dx_data) // NOLINT
}; };
class dx_iface final : public DRW_Interface class dx_iface final : public DRW_Interface
{ {
public: public:
dx_iface(const std::string& file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits); dx_iface(const std::string &file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits);
virtual ~dx_iface(); virtual ~dx_iface();
auto fileExport(bool binary) -> bool; auto fileExport(bool binary) -> bool;
void writeEntity(DRW_Entity* e); void writeEntity(DRW_Entity *e);
void AddXSpaceBlock(bool add) {dxfW->AddXSpaceBlock(add);} void AddXSpaceBlock(bool add) { dxfW->AddXSpaceBlock(add); }
auto ErrorString() const -> std::string; auto ErrorString() const -> std::string;
// reimplement virtual DRW_Interface functions // reimplement virtual DRW_Interface functions
// writer part, send all in class dx_data to writer // writer part, send all in class dx_data to writer
virtual void writeHeader(DRW_Header& data) override; virtual void writeHeader(DRW_Header &data) override;
virtual void writeBlocks() override; virtual void writeBlocks() override;
//only send the name, needed by the reader to prepare handles of blocks & blockRecords // only send the name, needed by the reader to prepare handles of blocks & blockRecords
virtual void writeBlockRecords() override; virtual void writeBlockRecords() override;
//write entities of model space and first paper_space // write entities of model space and first paper_space
virtual void writeEntities() override; virtual void writeEntities() override;
virtual void writeLTypes() override; virtual void writeLTypes() override;
virtual void writeLayers() override; virtual void writeLayers() override;
@ -121,9 +132,11 @@ public:
virtual void writeObjects() override; virtual void writeObjects() override;
virtual void writeAppId() override; virtual void writeAppId() override;
void AddEntity(DRW_Entity* e); void AddEntity(DRW_Entity *e);
auto AddFont(const QFont &f) -> UTF8STRING; auto AddFont(const QFont &f) -> UTF8STRING;
void AddBlock(dx_ifaceBlock* block); void AddBlock(dx_ifaceBlock *block);
static auto QtPenStyleToString(Qt::PenStyle style) -> UTF8STRING;
void AddQtLTypes(); void AddQtLTypes();
void AddDefLayers(); void AddDefLayers();
@ -134,8 +147,8 @@ public:
private: private:
Q_DISABLE_COPY_MOVE(dx_iface) // NOLINT Q_DISABLE_COPY_MOVE(dx_iface) // NOLINT
dxfRW* dxfW; //pointer to writer, needed to send data dxfRW *dxfW; // pointer to writer, needed to send data
dx_data cData; // class to store or read data dx_data cData; // class to store or read data
DRW::Version version; DRW::Version version;
void InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits); void InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits);

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,7 @@ class DRW_Point;
class DRW_ASTMNotch; class DRW_ASTMNotch;
struct VLayoutPassmark; struct VLayoutPassmark;
class DRW_ATTDEF; class DRW_ATTDEF;
class DRW_Circle;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
class VTextCodec; class VTextCodec;
@ -142,21 +143,30 @@ private:
void ExportAAMAOutline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMAOutline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADraw(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMADraw(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADrawSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMADrawSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADrawInternalPaths(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADrawPlaceLabels(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMAIntcut(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMANotch(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMAGrainline(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportPieceText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportPieceText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportStyleSystemText(const QSharedPointer<dx_iface> &input, const QVector<VLayoutPiece> &details); void ExportStyleSystemText(const QSharedPointer<dx_iface> &input, const QVector<VLayoutPiece> &details);
void ExportAAMADrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportAAMADrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAAMADrawFoldLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
auto ExportToASTM(const QVector<VLayoutPiece> &details) -> bool; auto ExportToASTM(const QVector<VLayoutPiece> &details) -> bool;
void ExportASTMPieceBoundary(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMPieceBoundary(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMSewLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMInternalLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMDrawInternalPaths(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMDrawPlaceLabels(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMInternalCutout(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMDrill(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail); void ExportASTMNotches(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMMirrorLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportASTMDrawFoldLine(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail);
void ExportAnnotationText(const QSharedPointer<dx_ifaceBlock> &detailBlock, const VLayoutPiece &detail,
const UTF8STRING &layer);
Q_REQUIRED_RESULT auto ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNotch *; Q_REQUIRED_RESULT auto ExportASTMNotch(const VLayoutPassmark &passmark) -> DRW_ASTMNotch *;
Q_REQUIRED_RESULT auto ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, const UTF8STRING &notchLayer, Q_REQUIRED_RESULT auto ExportASTMNotchDataDependecy(const VLayoutPassmark &passmark, const UTF8STRING &notchLayer,
@ -170,6 +180,7 @@ private:
Q_REQUIRED_RESULT auto AAMALine(const QLineF &line, const UTF8STRING &layer) -> DRW_Entity *; Q_REQUIRED_RESULT auto AAMALine(const QLineF &line, const UTF8STRING &layer) -> DRW_Entity *;
Q_REQUIRED_RESULT auto AAMAText(const QPointF &pos, const QString &text, const UTF8STRING &layer) -> DRW_Entity *; Q_REQUIRED_RESULT auto AAMAText(const QPointF &pos, const QString &text, const UTF8STRING &layer) -> DRW_Entity *;
Q_REQUIRED_RESULT auto AAMAPoint(const QPointF &pos, const UTF8STRING &layer) const -> DRW_Point *; Q_REQUIRED_RESULT auto AAMAPoint(const QPointF &pos, const UTF8STRING &layer) const -> DRW_Point *;
Q_REQUIRED_RESULT auto AAMACircle(const QPointF &pos, const UTF8STRING &layer, qreal radius) const -> DRW_Circle *;
template <class P, class V, class C> template <class P, class V, class C>
Q_REQUIRED_RESULT auto CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer, bool forceClosed) Q_REQUIRED_RESULT auto CreateAAMAPolygon(const QVector<C> &polygon, const UTF8STRING &layer, bool forceClosed)
@ -179,6 +190,16 @@ private:
auto GetFileNameForLocale() const -> std::string; auto GetFileNameForLocale() const -> std::string;
static auto NotchPrecedingPoint(const QVector<VLayoutPoint> &boundary, QPointF notchBase, QPointF &point) -> bool; static auto NotchPrecedingPoint(const QVector<VLayoutPoint> &boundary, QPointF notchBase, QPointF &point) -> bool;
void AAMADrawFoldLineTwoArrows(const QVector<QVector<QPointF>> &points,
const QSharedPointer<dx_ifaceBlock> &detailBlock);
void AAMADrawFoldLineThreeDots(const QVector<QVector<QPointF>> &points,
const QSharedPointer<dx_ifaceBlock> &detailBlock, qreal radius);
void AAMADrawFoldLineThreeX(const QVector<QVector<QPointF>> &points,
const QSharedPointer<dx_ifaceBlock> &detailBlock);
void ASTMDrawFoldLineTwoArrows(const QVector<QVector<QPointF>> &points,
const QSharedPointer<dx_ifaceBlock> &detailBlock);
}; };
#endif // VDXFENGINE_H #endif // VDXFENGINE_H

View File

@ -596,7 +596,7 @@ auto VAbstractCurve::DirectionArrows() const -> QVector<DirectionArrow>
} }
// Reverse line because we want start arrow from this point // Reverse line because we want start arrow from this point
arrow = QLineF(arrow.p2(), arrow.p1()); Swap(arrow);
const qreal angle = arrow.angle(); // we each time change line angle, better save original angle value const qreal angle = arrow.angle(); // we each time change line angle, better save original angle value
arrow.setLength(VAbstractCurve::LengthCurveDirectionArrow()); arrow.setLength(VAbstractCurve::LengthCurveDirectionArrow());

View File

@ -96,3 +96,18 @@ auto operator>>(QDataStream &dataStream, VLayoutPassmark &data) -> QDataStream &
return dataStream; return dataStream;
} }
//---------------------------------------------------------------------------------------------------------------------
auto SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width) -> QPointF
{
QLineF pLine(p1, p2);
pLine.setAngle(pLine.angle() + angle);
pLine.setLength(width);
return pLine.p2();
}
//---------------------------------------------------------------------------------------------------------------------
auto SimpleParallelLine(const QPointF &p1, const QPointF &p2, qreal width) -> QLineF
{
return {SingleParallelPoint(p1, p2, 90, width), SingleParallelPoint(p2, p1, -90, width)};
}

View File

@ -88,17 +88,25 @@ Q_DECLARE_METATYPE(VLayoutPassmark) // NOLINT
constexpr qreal accuracyPointOnLine = MmToPixel(0.1555); constexpr qreal accuracyPointOnLine = MmToPixel(0.1555);
Q_REQUIRED_RESULT static inline auto VFuzzyComparePoints(const QPointF &p1, const QPointF &p2, Q_REQUIRED_RESULT inline auto VFuzzyComparePoints(const QPointF &p1, const QPointF &p2,
qreal accuracy = accuracyPointOnLine) -> bool; qreal accuracy = accuracyPointOnLine) -> bool;
static inline auto VFuzzyComparePoints(const QPointF &p1, const QPointF &p2, qreal accuracy) -> bool inline auto VFuzzyComparePoints(const QPointF &p1, const QPointF &p2, qreal accuracy) -> bool
{ {
return QLineF(p1, p2).length() <= accuracy; return QLineF(p1, p2).length() <= accuracy;
} }
Q_REQUIRED_RESULT static inline auto VFuzzyOnAxis(qreal v1, qreal v2, qreal accuracy = accuracyPointOnLine) -> bool; Q_REQUIRED_RESULT inline auto VFuzzyOnAxis(qreal v1, qreal v2, qreal accuracy = accuracyPointOnLine) -> bool;
static inline auto VFuzzyOnAxis(qreal v1, qreal v2, qreal accuracy) -> bool inline auto VFuzzyOnAxis(qreal v1, qreal v2, qreal accuracy) -> bool
{ {
return qAbs(v1 - v2) <= accuracy; return qAbs(v1 - v2) <= accuracy;
} }
template <class T> inline void Swap(T &line)
{
line = T(line.p2(), line.p1());
}
auto SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width) -> QPointF;
auto SimpleParallelLine(const QPointF &p1, const QPointF &p2, qreal width) -> QLineF;
#endif // VGEOMETRYDEF_H #endif // VGEOMETRYDEF_H

View File

@ -36,8 +36,8 @@
#include <QVector> #include <QVector>
#include <QtGlobal> #include <QtGlobal>
#include "vgeometrydef.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "vgeometrydef.h"
class QLineF; class QLineF;
class QPoint; class QPoint;
@ -62,7 +62,7 @@ public:
virtual ~VGObject(); virtual ~VGObject();
auto operator= (const VGObject &obj) -> VGObject&; auto operator=(const VGObject &obj) -> VGObject &;
#ifdef Q_COMPILER_RVALUE_REFS #ifdef Q_COMPILER_RVALUE_REFS
VGObject(VGObject &&obj) noexcept; VGObject(VGObject &&obj) noexcept;
auto operator=(VGObject &&obj) noexcept -> VGObject &; auto operator=(VGObject &&obj) noexcept -> VGObject &;
@ -95,38 +95,37 @@ public:
virtual auto ToJson() const -> QJsonObject; virtual auto ToJson() const -> QJsonObject;
static auto BuildLine(const QPointF &p1, const qreal& length, const qreal &angle) -> QLineF; static auto BuildLine(const QPointF &p1, const qreal &length, const qreal &angle) -> QLineF;
static auto BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect) -> QPointF; static auto BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect) -> QPointF;
static auto BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect) -> QLineF; static auto BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect) -> QLineF;
static auto BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &scRect) -> QLineF; static auto BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &scRect) -> QLineF;
static auto ContactPoints (const QPointF &p, const QPointF &center, qreal radius, QPointF &p1, QPointF &p2) -> int; static auto ContactPoints(const QPointF &p, const QPointF &center, qreal radius, QPointF &p1, QPointF &p2) -> int;
static auto LineIntersectRect(const QRectF &rec, const QLineF &line) -> QPointF; static auto LineIntersectRect(const QRectF &rec, const QLineF &line) -> QPointF;
static auto IntersectionCircles(const QPointF &c1, double r1, const QPointF &c2, double r2, QPointF &p1, static auto IntersectionCircles(const QPointF &c1, double r1, const QPointF &c2, double r2, QPointF &p1,
QPointF &p2) -> int; QPointF &p2) -> int;
static auto LineIntersectCircle(const QPointF &center, qreal radius, const QLineF &line, QPointF &p1, static auto LineIntersectCircle(const QPointF &center, qreal radius, const QLineF &line, QPointF &p1, QPointF &p2)
QPointF &p2) -> qint32; -> qint32;
static auto ClosestPoint(const QLineF &line, const QPointF &point) -> QPointF; static auto ClosestPoint(const QLineF &line, const QPointF &point) -> QPointF;
static auto addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k) -> QPointF; static auto addVector(const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k) -> QPointF;
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c); static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c);
static auto IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2, static auto IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2,
qreal accuracy = accuracyPointOnLine) -> bool; qreal accuracy = accuracyPointOnLine) -> bool;
static auto IsLineSegmentOnLineSegment (const QLineF &seg1, const QLineF &seg2, static auto IsLineSegmentOnLineSegment(const QLineF &seg1, const QLineF &seg2, qreal accuracy = accuracyPointOnLine)
qreal accuracy = accuracyPointOnLine) -> bool; -> bool;
static auto CorrectDistortion(const QPointF &t, const QPointF &p1, const QPointF &p2) -> QPointF; static auto CorrectDistortion(const QPointF &t, const QPointF &p1, const QPointF &p2) -> QPointF;
static auto IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2, static auto IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2,
qreal accuracy = accuracyPointOnLine) -> bool; qreal accuracy = accuracyPointOnLine) -> bool;
static auto GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints) -> int; static auto GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints) -> int;
template <class T> template <class T> static auto PainterPath(const QVector<T> &points) -> QPainterPath;
static auto PainterPath(const QVector<T> &points) -> QPainterPath;
protected:
static auto FlippingMatrix(const QLineF &axis) -> QTransform; static auto FlippingMatrix(const QLineF &axis) -> QTransform;
private: private:
QSharedDataPointer<VGObjectData> d; QSharedDataPointer<VGObjectData> d;
static auto PointInCircle (const QPointF &p, const QPointF &center, qreal radius) -> int; static auto PointInCircle(const QPointF &p, const QPointF &center, qreal radius) -> int;
}; };
QT_WARNING_POP QT_WARNING_POP
@ -134,8 +133,7 @@ QT_WARNING_POP
Q_DECLARE_TYPEINFO(VGObject, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VGObject, Q_MOVABLE_TYPE); // NOLINT
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
template <class T> template <class T> inline auto VGObject::PainterPath(const QVector<T> &points) -> QPainterPath
inline auto VGObject::PainterPath(const QVector<T> &points) -> QPainterPath
{ {
QPainterPath path; QPainterPath path;
path.setFillRule(Qt::WindingFill); path.setFillRule(Qt::WindingFill);

View File

@ -50,7 +50,8 @@ VLayoutPlaceLabel::VLayoutPlaceLabel(const VPlaceLabelItem &item)
: m_center(item.toQPointF()), : m_center(item.toQPointF()),
m_type(item.GetLabelType()), m_type(item.GetLabelType()),
m_rotationMatrix(item.RotationMatrix()), m_rotationMatrix(item.RotationMatrix()),
m_box(item.Box()) m_box(item.Box()),
m_notMirrored(item.IsNotMirrored())
{ {
} }
@ -66,7 +67,8 @@ auto operator<<(QDataStream &dataStream, const VLayoutPlaceLabel &data) -> QData
dataStream << data.m_rotationMatrix; dataStream << data.m_rotationMatrix;
dataStream << data.m_box; dataStream << data.m_box;
// Added in classVersion = 2 // Added in classVersion = 3
dataStream << data.m_notMirrored;
return dataStream; return dataStream;
} }
@ -110,10 +112,10 @@ auto operator>>(QDataStream &dataStream, VLayoutPlaceLabel &data) -> QDataStream
dataStream >> data.m_rotationMatrix; dataStream >> data.m_rotationMatrix;
dataStream >> data.m_box; dataStream >> data.m_box;
// if (actualClassVersion >= 2) if (actualClassVersion >= 3)
// { {
dataStream >> data.m_notMirrored;
// } }
return dataStream; return dataStream;
} }

View File

@ -39,8 +39,8 @@ public:
VLayoutPlaceLabel() = default; VLayoutPlaceLabel() = default;
explicit VLayoutPlaceLabel(const VPlaceLabelItem &item); explicit VLayoutPlaceLabel(const VPlaceLabelItem &item);
friend auto operator<<(QDataStream& dataStream, const VLayoutPlaceLabel& data) -> QDataStream&; friend auto operator<<(QDataStream &dataStream, const VLayoutPlaceLabel &data) -> QDataStream &;
friend auto operator>>(QDataStream& dataStream, VLayoutPlaceLabel& data) -> QDataStream&; friend auto operator>>(QDataStream &dataStream, VLayoutPlaceLabel &data) -> QDataStream &;
auto Center() const -> QPointF; auto Center() const -> QPointF;
void SetCenter(QPointF newCenter); void SetCenter(QPointF newCenter);
@ -54,17 +54,21 @@ public:
auto Box() const -> const QRectF &; auto Box() const -> const QRectF &;
void SetBox(const QRectF &newBox); void SetBox(const QRectF &newBox);
auto IsNotMirrored() const -> bool;
void SetNotMirrored(bool newNotMirrored);
private: private:
static constexpr quint32 streamHeader = 0xB282E284; // CRC-32Q string "VLayoutPlaceLabel" static constexpr quint32 streamHeader = 0xB282E284; // CRC-32Q string "VLayoutPlaceLabel"
static constexpr quint16 classVersion = 2; static constexpr quint16 classVersion = 3;
QPointF m_center{}; QPointF m_center{};
PlaceLabelType m_type{PlaceLabelType::Button}; PlaceLabelType m_type{PlaceLabelType::Button};
QTransform m_rotationMatrix{}; QTransform m_rotationMatrix{};
QRectF m_box{}; QRectF m_box{};
bool m_notMirrored{false};
}; };
Q_DECLARE_METATYPE(VLayoutPlaceLabel) // NOLINT Q_DECLARE_METATYPE(VLayoutPlaceLabel) // NOLINT
Q_DECLARE_TYPEINFO(VLayoutPlaceLabel, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VLayoutPlaceLabel, Q_MOVABLE_TYPE); // NOLINT
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -115,4 +119,16 @@ inline void VLayoutPlaceLabel::SetBox(const QRectF &newBox)
m_box = newBox; m_box = newBox;
} }
//---------------------------------------------------------------------------------------------------------------------
inline auto VLayoutPlaceLabel::IsNotMirrored() const -> bool
{
return m_notMirrored;
}
//---------------------------------------------------------------------------------------------------------------------
inline void VLayoutPlaceLabel::SetNotMirrored(bool newNotMirrored)
{
m_notMirrored = newNotMirrored;
}
#endif // VLAYOUTPLACELABEL_H #endif // VLAYOUTPLACELABEL_H

View File

@ -195,6 +195,18 @@ void VPlaceLabelItem::SetLabelType(PlaceLabelType type)
d->type = type; d->type = type;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VPlaceLabelItem::IsNotMirrored() const -> bool
{
return d->notMirrored;
}
//---------------------------------------------------------------------------------------------------------------------
void VPlaceLabelItem::SetNotMirrored(bool value)
{
d->notMirrored = value;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VPlaceLabelItem::RotationMatrix() const -> QTransform auto VPlaceLabelItem::RotationMatrix() const -> QTransform
{ {

View File

@ -81,6 +81,9 @@ public:
auto GetLabelType() const -> PlaceLabelType; auto GetLabelType() const -> PlaceLabelType;
void SetLabelType(PlaceLabelType type); void SetLabelType(PlaceLabelType type);
auto IsNotMirrored() const -> bool;
void SetNotMirrored(bool value);
auto RotationMatrix() const -> QTransform; auto RotationMatrix() const -> QTransform;
auto Box() const -> QRectF; auto Box() const -> QRectF;

View File

@ -54,6 +54,7 @@ public:
qreal aValue{0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal aValue{0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal correctionAngle{0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal correctionAngle{0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal isVisible{1}; // NOLINT(misc-non-private-member-variables-in-classes) qreal isVisible{1}; // NOLINT(misc-non-private-member-variables-in-classes)
bool notMirrored{false}; // NOLINT(misc-non-private-member-variables-in-classes)
private: private:
Q_DISABLE_ASSIGN_MOVE(VPlaceLabelItemData) // NOLINT Q_DISABLE_ASSIGN_MOVE(VPlaceLabelItemData) // NOLINT

View File

@ -30,6 +30,7 @@
#include "../vformat/vsinglelineoutlinechar.h" #include "../vformat/vsinglelineoutlinechar.h"
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vlayout/vboundary.h" #include "../vlayout/vboundary.h"
#include "../vlayout/vfoldline.h"
#include "../vlayout/vlayoutpiece.h" #include "../vlayout/vlayoutpiece.h"
#include "../vlayout/vlayoutpiecepath.h" #include "../vlayout/vlayoutpiecepath.h"
#include "../vlayout/vlayoutpoint.h" #include "../vlayout/vlayoutpoint.h"
@ -70,6 +71,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, mPG, ("PG"_L1)) // NOLINT page feed
Q_GLOBAL_STATIC_WITH_ARGS(const QString, mPA, ("PA"_L1)) // NOLINT plot absolute Q_GLOBAL_STATIC_WITH_ARGS(const QString, mPA, ("PA"_L1)) // NOLINT plot absolute
Q_GLOBAL_STATIC_WITH_ARGS(const QString, mPW, ("PW"_L1)) // NOLINT pen width Q_GLOBAL_STATIC_WITH_ARGS(const QString, mPW, ("PW"_L1)) // NOLINT pen width
Q_GLOBAL_STATIC_WITH_ARGS(const QString, mLA, ("LA"_L1)) // NOLINT line attributes Q_GLOBAL_STATIC_WITH_ARGS(const QString, mLA, ("LA"_L1)) // NOLINT line attributes
Q_GLOBAL_STATIC_WITH_ARGS(const QString, mCI, ("CI"_L1)) // NOLINT circle
QT_WARNING_POP QT_WARNING_POP
@ -162,12 +164,17 @@ inline auto LineAlign(const TextLine &tl, const QString &text, const QFontMetric
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto LineMatrix(const VLayoutPiece &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos, auto LineMatrix(const VLayoutPiece &piece, const QPointF &topLeft, qreal angle, const QPointF &linePos,
int maxLineWidth, qreal maxLabelHeight) -> QTransform int maxLineWidth) -> QTransform
{ {
QTransform labelMatrix; QTransform labelMatrix;
labelMatrix.translate(topLeft.x(), topLeft.y()); labelMatrix.translate(topLeft.x(), topLeft.y());
if (piece.IsVerticallyFlipped() || piece.IsHorizontallyFlipped()) if ((piece.IsVerticallyFlipped() && piece.IsHorizontallyFlipped()) ||
(!piece.IsVerticallyFlipped() && !piece.IsHorizontallyFlipped()))
{
labelMatrix.rotate(angle);
}
else if (piece.IsVerticallyFlipped() || piece.IsHorizontallyFlipped())
{ {
if (piece.IsVerticallyFlipped()) if (piece.IsVerticallyFlipped())
{ {
@ -178,15 +185,11 @@ auto LineMatrix(const VLayoutPiece &piece, const QPointF &topLeft, qreal angle,
if (piece.IsHorizontallyFlipped()) if (piece.IsHorizontallyFlipped())
{ {
labelMatrix.scale(1, -1); labelMatrix.scale(-1, 1);
labelMatrix.rotate(-angle); labelMatrix.rotate(-angle);
labelMatrix.translate(0, -maxLabelHeight); labelMatrix.translate(-maxLineWidth, 0);
} }
} }
else
{
labelMatrix.rotate(angle);
}
labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position labelMatrix.translate(linePos.x(), linePos.y()); // Each string has own position
labelMatrix *= piece.GetMatrix(); labelMatrix *= piece.GetMatrix();
@ -230,72 +233,6 @@ auto NextPattern(int patternIndex, const QVector<int> &pattern) -> int
{ {
return (patternIndex + 2) % static_cast<int>(pattern.size()); return (patternIndex + 2) % static_cast<int>(pattern.size());
} }
//---------------------------------------------------------------------------------------------------------------------
auto LabelHeightSVGFont(const VLayoutPiece &detail, const QVector<TextLine> &labelLines, const VSvgFont &svgFont,
const VSvgFontDatabase *db, qreal penWidth, qreal dH, int spacing) -> qreal
{
qreal labelHeight = 0;
if (detail.IsHorizontallyFlipped())
{
for (int i = 0; i < labelLines.size(); ++i)
{
const VSvgFont fnt = LineFont(labelLines.at(i), svgFont);
VSvgFontEngine engine = db->FontEngine(fnt);
const qreal lineHeight = engine.FontHeight() + penWidth;
if (labelHeight + lineHeight > dH)
{
break;
}
if (i < labelLines.size() - 1)
{
labelHeight += lineHeight + spacing;
}
else
{
labelHeight += lineHeight;
}
}
}
return labelHeight;
}
//---------------------------------------------------------------------------------------------------------------------
auto LabelHeightOutlineFont(const VLayoutPiece &detail, const QVector<TextLine> &labelLines, const QFont &font,
qreal penWidth, qreal dH, int spacing) -> qreal
{
qreal labelHeight = 0;
if (detail.IsHorizontallyFlipped())
{
for (int i = 0; i < labelLines.size(); ++i)
{
const QFont fnt = LineFont(labelLines.at(i), font);
QFontMetrics fm(fnt);
const qreal lineHeight = fm.height() + penWidth;
if (labelHeight + lineHeight > dH)
{
break;
}
if (i < labelLines.size() - 1)
{
labelHeight += lineHeight + spacing;
}
else
{
labelHeight += lineHeight;
}
}
}
return labelHeight;
}
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -455,9 +392,11 @@ void VHPGLEngine::ExportDetails(QTextStream &out, const QList<VLayoutPiece> &det
PlotSewLine(out, detail); PlotSewLine(out, detail);
PlotInternalPaths(out, detail); PlotInternalPaths(out, detail);
PlotGrainline(out, detail); PlotGrainline(out, detail);
PlotMirrorLine(out, detail);
PlotPlaceLabels(out, detail); PlotPlaceLabels(out, detail);
PlotPassmarks(out, detail); PlotPassmarks(out, detail);
PlotLabels(out, detail); PlotLabels(out, detail);
PlotFoldLine(out, detail);
} }
} }
@ -474,17 +413,21 @@ void VHPGLEngine::PlotSewLine(QTextStream &out, const VLayoutPiece &detail)
{ {
if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn()) if (detail.IsSeamAllowance() && not detail.IsHideMainPath() && not detail.IsSeamAllowanceBuiltIn())
{ {
QVector<VLayoutPoint> sewLine = detail.GetMappedContourPoints(); QVector<VLayoutPoint> const sewLine = detail.GetMappedFullContourPoints();
if (m_togetherWithNotches) if (m_togetherWithNotches)
{ {
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks(); const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn(); bool const seamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn(); bool const builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(sewLine, seamAllowance, builtInSeamAllowance); VBoundary boundary(sewLine, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName()); boundary.SetPieceName(detail.GetName());
if (detail.IsShowFullPiece() && !detail.GetMappedSeamMirrorLine().isNull())
{
boundary.SetMirrorLine(detail.GetMappedSeamMirrorLine());
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, true, false); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, true, false);
for (const auto &item : sequence) for (const auto &item : sequence)
@ -511,18 +454,22 @@ void VHPGLEngine::PlotSewLine(QTextStream &out, const VLayoutPiece &detail)
void VHPGLEngine::PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail) void VHPGLEngine::PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail)
{ {
QVector<VLayoutPoint> pieceBoundary = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn() QVector<VLayoutPoint> pieceBoundary = detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn()
? detail.GetMappedSeamAllowancePoints() ? detail.GetMappedFullSeamAllowancePoints()
: detail.GetMappedContourPoints(); : detail.GetMappedFullContourPoints();
if (m_togetherWithNotches) if (m_togetherWithNotches)
{ {
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks(); const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
bool seamAllowance = detail.IsSeamAllowance() && !detail.IsSeamAllowanceBuiltIn(); bool const seamAllowance = detail.IsSeamAllowance() && !detail.IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn(); bool const builtInSeamAllowance = detail.IsSeamAllowance() && detail.IsSeamAllowanceBuiltIn();
VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance); VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(detail.GetName()); boundary.SetPieceName(detail.GetName());
if (detail.IsShowFullPiece() && !detail.GetMappedSeamAllowanceMirrorLine().isNull())
{
boundary.SetMirrorLine(detail.GetMappedSeamAllowanceMirrorLine());
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, false);
pieceBoundary.clear(); pieceBoundary.clear();
@ -548,25 +495,50 @@ void VHPGLEngine::PlotSeamAllowance(QTextStream &out, const VLayoutPiece &detail
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotInternalPaths(QTextStream &out, const VLayoutPiece &detail) void VHPGLEngine::PlotInternalPaths(QTextStream &out, const VLayoutPiece &detail)
{ {
QVector<VLayoutPiecePath> internalPaths = detail.GetInternalPaths(); QVector<VLayoutPiecePath> const internalPaths = detail.GetInternalPaths();
for (const auto &path : internalPaths) for (const auto &path : internalPaths)
{ {
QVector<VLayoutPoint> points = VLayoutPiece::MapVector( QVector<VLayoutPoint> points = VLayoutPiece::MapVector(
path.Points(), detail.GetMatrix(), detail.IsVerticallyFlipped() || detail.IsHorizontallyFlipped()); path.Points(), detail.GetMatrix(), detail.IsVerticallyFlipped() || detail.IsHorizontallyFlipped());
PlotPath(out, CastToPoint(ConvertPath(points)), path.PenStyle()); PlotPath(out, CastToPoint(ConvertPath(points)), path.PenStyle());
if (!path.IsNotMirrored() && detail.IsShowFullPiece() && !detail.GetMappedSeamMirrorLine().isNull())
{
const QTransform matrix = VGObject::FlippingMatrix(detail.GetMappedSeamMirrorLine());
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const VLayoutPoint &point) { return VAbstractPiece::MapPoint(point, matrix); });
PlotPath(out, CastToPoint(ConvertPath(points)), path.PenStyle());
}
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotPlaceLabels(QTextStream &out, const VLayoutPiece &detail) void VHPGLEngine::PlotPlaceLabels(QTextStream &out, const VLayoutPiece &detail)
{ {
auto PlotShape = [this, &out](const PlaceLabelImg &shape)
{
for (const auto &subShape : shape)
{
PlotPath(out, CastToPoint(ConvertPath(subShape)), Qt::SolidLine);
}
};
const QVector<VLayoutPlaceLabel> placeLabels = detail.GetPlaceLabels(); const QVector<VLayoutPlaceLabel> placeLabels = detail.GetPlaceLabels();
for (const auto &pLabel : placeLabels) for (const auto &pLabel : placeLabels)
{ {
PlaceLabelImg shape = detail.MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(pLabel)); PlotShape(detail.MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(pLabel)));
for (auto &subShape : shape)
if (!pLabel.IsNotMirrored() && detail.IsShowFullPiece() && !detail.GetMappedSeamMirrorLine().isNull())
{ {
PlotPath(out, CastToPoint(ConvertPath(subShape)), Qt::SolidLine); PlaceLabelImg shape = detail.MapPlaceLabelShape(VAbstractPiece::PlaceLabelShape(pLabel));
const QTransform matrix = VGObject::FlippingMatrix(detail.GetMappedSeamMirrorLine());
for (auto &points : shape)
{
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const VLayoutPoint &point) { return VAbstractPiece::MapPoint(point, matrix); });
}
PlotShape(shape);
} }
} }
} }
@ -579,14 +551,31 @@ void VHPGLEngine::PlotPassmarks(QTextStream &out, const VLayoutPiece &detail)
return; return;
} }
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks(); auto PlotPassmark = [this, &out](const VLayoutPassmark &passmark)
for (const auto &passmark : passmarks)
{ {
for (const auto &subLine : passmark.lines) for (const auto &subLine : passmark.lines)
{ {
HPPenUp(out, ConvertPoint(subLine.p1()).toPoint()); HPPenUp(out, ConvertPoint(subLine.p1()).toPoint());
HPPenDown(out, ConvertPoint(subLine.p2()).toPoint()); HPPenDown(out, ConvertPoint(subLine.p2()).toPoint());
} }
};
const QVector<VLayoutPassmark> passmarks = detail.GetMappedPassmarks();
for (const auto &passmark : passmarks)
{
PlotPassmark(passmark);
const QLineF mirrorLine = detail.GetMappedSeamMirrorLine();
if (!mirrorLine.isNull() && detail.IsShowFullPiece())
{
if (!VGObject::IsPointOnLineviaPDP(passmark.baseLine.p1(), mirrorLine.p1(), mirrorLine.p2()))
{
const QTransform matrix = VGObject::FlippingMatrix(mirrorLine);
const VLayoutPassmark mirroredPassmark = VLayoutPiece::MapPassmark(passmark, matrix, false);
PlotPassmark(mirroredPassmark);
}
}
} }
} }
@ -605,13 +594,128 @@ void VHPGLEngine::PlotGrainline(QTextStream &out, const VLayoutPiece &detail)
return; return;
} }
GrainlineShape shape = detail.GetMappedGrainlineShape(); GrainlineShape const shape = detail.GetMappedGrainlineShape();
for (const auto &subShape : shape) for (const auto &subShape : shape)
{ {
PlotPath(out, CastToPoint(ConvertPath(subShape)), Qt::SolidLine); PlotPath(out, CastToPoint(ConvertPath(subShape)), Qt::SolidLine);
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotMirrorLine(QTextStream &out, const VLayoutPiece &detail)
{
if (detail.IsShowFullPiece())
{
const QLineF mirrorLine = detail.GetMappedSeamAllowanceMirrorLine();
if (not mirrorLine.isNull())
{
PlotPath(out, CastToPoint(ConvertPath<QPointF>({mirrorLine.p1(), mirrorLine.p2()})), Qt::DashDotLine);
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotFoldLine(QTextStream &out, const VLayoutPiece &detail)
{
VFoldLine const fLine = detail.FoldLine();
switch (detail.GetFoldLineType())
{
case FoldLineType::TwoArrows:
case FoldLineType::TwoArrowsTextAbove:
case FoldLineType::TwoArrowsTextUnder:
PlotFoldTwoArrowsText(out, fLine);
break;
case FoldLineType::ThreeDots:
PlotFoldThreeDots(out, fLine);
break;
case FoldLineType::ThreeX:
PlotFoldThreeX(out, fLine);
break;
case FoldLineType::LAST_ONE_DO_NOT_USE:
Q_UNREACHABLE();
break;
case FoldLineType::Text:
PlotFoldLineText(out, fLine);
break;
case FoldLineType::None:
default:
break;
};
}
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotFoldLineText(QTextStream &out, const VFoldLine &fLine)
{
QVector<QPainterPath> const path = fLine.FoldLinePath();
if (!path.isEmpty())
{
PlotPainterPath(out, path.constFirst(), Qt::SolidLine);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotFoldThreeX(QTextStream &out, const VFoldLine &fLine)
{
QVector<QVector<QPointF>> const points = fLine.FoldLineMarkPoints();
if (points.isEmpty())
{
return;
}
QVector<QPointF> const &shape = points.constFirst();
for (int i = 0; i < shape.size() - 1; i += 2)
{
HPPenUp(out, ConvertPoint(shape.at(i)).toPoint());
HPPenDown(out, ConvertPoint(shape.at(i + 1)).toPoint());
}
}
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotFoldTwoArrowsText(QTextStream &out, const VFoldLine &fLine)
{
QVector<QVector<QPointF>> points = fLine.FoldLineMarkPoints();
if (points.isEmpty() || points.size() != 3)
{
return;
}
points.removeAt(1);
QVector<QPointF> shape;
for (const auto &subShape : points)
{
shape += subShape;
}
const auto arrows = CastToPoint(ConvertPath(shape));
PlotPath(out, arrows, Qt::SolidLine);
QVector<QPainterPath> const path = fLine.FoldLinePath();
if (path.size() > 1)
{
PlotPainterPath(out, path.constLast(), Qt::SolidLine);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotFoldThreeDots(QTextStream &out, const VFoldLine &fLine)
{
QVector<QVector<QPointF>> const points = fLine.FoldLineMarkPoints();
if (points.isEmpty() || points.constFirst().size() != 3)
{
return;
}
QVector<QPointF> const &shape = points.constFirst();
qreal const radius = fLine.ThreeDotsRadius();
for (const auto &center : shape)
{
PlotCircle(out, center, radius);
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotLabel(QTextStream &out, const VLayoutPiece &detail, const QVector<QPointF> &labelShape, void VHPGLEngine::PlotLabel(QTextStream &out, const VLayoutPiece &detail, const QVector<QPointF> &labelShape,
const VTextManager &tm) const VTextManager &tm)
@ -639,7 +743,7 @@ void VHPGLEngine::PlotLabelSVGFont(QTextStream &out, const VLayoutPiece &detail,
VSvgFontEngine engine = VSvgFontEngine engine =
db->FontEngine(tm.GetSVGFontFamily(), SVGFontStyle::Normal, SVGFontWeight::Normal, tm.GetSVGFontPointSize()); db->FontEngine(tm.GetSVGFontFamily(), SVGFontStyle::Normal, SVGFontWeight::Normal, tm.GetSVGFontPointSize());
VSvgFont svgFont = engine.Font(); VSvgFont const svgFont = engine.Font();
if (!svgFont.IsValid()) if (!svgFont.IsValid())
{ {
qDebug() << QStringLiteral("Invalid SVG font '%1'. Fallback to outline font.").arg(svgFont.Name()); qDebug() << QStringLiteral("Invalid SVG font '%1'. Fallback to outline font.").arg(svgFont.Name());
@ -656,8 +760,6 @@ void VHPGLEngine::PlotLabelSVGFont(QTextStream &out, const VLayoutPiece &detail,
const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), svgFont, m_penWidthPx); const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), svgFont, m_penWidthPx);
const qreal labelHeight = LabelHeightSVGFont(detail, labelLines, svgFont, db, m_penWidthPx, dH, tm.GetSpacing());
for (const auto &tl : labelLines) for (const auto &tl : labelLines)
{ {
const VSvgFont fnt = LineFont(tl, svgFont); const VSvgFont fnt = LineFont(tl, svgFont);
@ -671,10 +773,9 @@ void VHPGLEngine::PlotLabelSVGFont(QTextStream &out, const VLayoutPiece &detail,
const QString qsText = tl.m_qsText; const QString qsText = tl.m_qsText;
const qreal dX = LineAlign(tl, qsText, engine, dW, m_penWidthPx); const qreal dX = LineAlign(tl, qsText, engine, dW, m_penWidthPx);
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
const QTransform lineMatrix = const QTransform lineMatrix = LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth);
LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth, labelHeight);
QPainterPath path = lineMatrix.map(engine.DrawPath(QPointF(), qsText)); QPainterPath const path = lineMatrix.map(engine.DrawPath(QPointF(), qsText));
PlotPainterPath(out, path, Qt::SolidLine); PlotPainterPath(out, path, Qt::SolidLine);
dY += engine.FontHeight() + m_penWidthPx + tm.GetSpacing(); dY += engine.FontHeight() + m_penWidthPx + tm.GetSpacing();
@ -706,20 +807,17 @@ void VHPGLEngine::PlotLabelOutlineFont(QTextStream &out, const VLayoutPiece &det
const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), tm.GetFont()); const QVector<TextLine> labelLines = tm.GetLabelSourceLines(qFloor(dW), tm.GetFont());
const qreal labelHeight =
LabelHeightOutlineFont(detail, labelLines, tm.GetFont(), m_penWidthPx, dH, tm.GetSpacing());
for (const auto &tl : labelLines) for (const auto &tl : labelLines)
{ {
const QFont fnt = LineFont(tl, tm.GetFont()); const QFont fnt = LineFont(tl, tm.GetFont());
VSingleLineOutlineChar corrector(fnt); VSingleLineOutlineChar const corrector(fnt);
if (m_singleStrokeOutlineFont && !corrector.IsPopulated()) if (m_singleStrokeOutlineFont && !corrector.IsPopulated())
{ {
corrector.LoadCorrections(settings->GetPathFontCorrections()); corrector.LoadCorrections(settings->GetPathFontCorrections());
} }
QFontMetrics fm(fnt); QFontMetrics const fm(fnt);
if (dY + fm.height() > dH) if (dY + fm.height() > dH)
{ {
@ -729,8 +827,7 @@ void VHPGLEngine::PlotLabelOutlineFont(QTextStream &out, const VLayoutPiece &det
const QString qsText = tl.m_qsText; const QString qsText = tl.m_qsText;
const qreal dX = LineAlign(tl, qsText, fm, dW); const qreal dX = LineAlign(tl, qsText, fm, dW);
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
const QTransform lineMatrix = const QTransform lineMatrix = LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth);
LineMatrix(detail, labelShape.at(0), angle, QPointF(dX, dY), maxLineWidth, labelHeight);
QPainterPath path; QPainterPath path;
@ -777,7 +874,7 @@ template <class T> auto VHPGLEngine::ConvertPoint(T point) const -> T
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotPath(QTextStream &out, QVector<QPoint> path, Qt::PenStyle penStyle) void VHPGLEngine::PlotPath(QTextStream &out, const QVector<QPoint> &path, Qt::PenStyle penStyle)
{ {
if (penStyle == Qt::NoPen) if (penStyle == Qt::NoPen)
{ {
@ -796,22 +893,22 @@ void VHPGLEngine::PlotPath(QTextStream &out, QVector<QPoint> path, Qt::PenStyle
} }
else else
{ {
QVector<int> patetrn = PatternForStyle(penStyle); QVector<int> const patetrn = PatternForStyle(penStyle);
PlotPathForStyle(out, path, patetrn); PlotPathForStyle(out, path, patetrn);
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotSolidLinePath(QTextStream &out, QVector<QPoint> path) void VHPGLEngine::PlotSolidLinePath(QTextStream &out, const QVector<QPoint> &path)
{ {
if (path.size() < 2) if (path.size() < 2)
{ {
HPPenUp(out, path.first()); HPPenUp(out, path.constFirst());
HPPenDown(out); HPPenDown(out);
return; return;
} }
HPPenUp(out, path.first()); HPPenUp(out, path.constFirst());
for (int i = 1; i < path.size(); ++i) for (int i = 1; i < path.size(); ++i)
{ {
@ -845,13 +942,13 @@ void VHPGLEngine::PlotPathForStyle(QTextStream &out, QVector<QPoint> path, QVect
for (int i = 1; i < path.size(); ++i) for (int i = 1; i < path.size(); ++i)
{ {
QPointF prevPoint = path.at(i - 1); QPointF prevPoint = path.at(i - 1);
QPoint currPoint = path.at(i); QPoint const currPoint = path.at(i);
qreal distance = QLineF(prevPoint, currPoint).length(); qreal const distance = QLineF(prevPoint, currPoint).length();
qreal segmentDistance = 0; qreal segmentDistance = 0;
do do
{ {
qreal subDistance = QLineF(prevPoint, currPoint).length(); qreal const subDistance = QLineF(prevPoint, currPoint).length();
patternDistance = CurrentPatternDistance(patternDistance, dashMode, pattern, patternIndex); patternDistance = CurrentPatternDistance(patternDistance, dashMode, pattern, patternIndex);
if (subDistance < patternDistance) if (subDistance < patternDistance)
@ -913,6 +1010,13 @@ void VHPGLEngine::PlotPainterPath(QTextStream &out, const QPainterPath &path, Qt
} }
} }
//---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::PlotCircle(QTextStream &out, const QPointF &center, qreal radius)
{
HPPenUp(out, ConvertPoint(center).toPoint());
HPComand(out, *mCI, QString::number(qFloor(ConvertPixels(radius))));
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VHPGLEngine::HPPenUp(QTextStream &out, QPoint point) void VHPGLEngine::HPPenUp(QTextStream &out, QPoint point)
{ {

View File

@ -47,6 +47,7 @@ class VLayoutPoint;
class QTextStream; class QTextStream;
class VTextManager; class VTextManager;
class QPainterPath; class QPainterPath;
class VFoldLine;
class VHPGLEngine class VHPGLEngine
{ {
@ -121,6 +122,13 @@ private:
void PlotPassmarks(QTextStream &out, const VLayoutPiece &detail); void PlotPassmarks(QTextStream &out, const VLayoutPiece &detail);
void PlotLabels(QTextStream &out, const VLayoutPiece &detail); void PlotLabels(QTextStream &out, const VLayoutPiece &detail);
void PlotGrainline(QTextStream &out, const VLayoutPiece &detail); void PlotGrainline(QTextStream &out, const VLayoutPiece &detail);
void PlotMirrorLine(QTextStream &out, const VLayoutPiece &detail);
void PlotFoldLine(QTextStream &out, const VLayoutPiece &detail);
void PlotFoldLineText(QTextStream &out, const VFoldLine &fLine);
void PlotFoldThreeX(QTextStream &out, const VFoldLine &fLine);
void PlotFoldTwoArrowsText(QTextStream &out, const VFoldLine &fLine);
void PlotFoldThreeDots(QTextStream &out, const VFoldLine &fLine);
void PlotLabel(QTextStream &out, const VLayoutPiece &detail, const QVector<QPointF> &labelShape, void PlotLabel(QTextStream &out, const VLayoutPiece &detail, const QVector<QPointF> &labelShape,
const VTextManager &tm); const VTextManager &tm);
@ -131,10 +139,11 @@ private:
template <class T> auto ConvertPath(const QVector<T> &path) const -> QVector<T>; template <class T> auto ConvertPath(const QVector<T> &path) const -> QVector<T>;
template <class T> auto ConvertPoint(T point) const -> T; template <class T> auto ConvertPoint(T point) const -> T;
void PlotPath(QTextStream &out, QVector<QPoint> path, Qt::PenStyle penStyle); void PlotPath(QTextStream &out, const QVector<QPoint> &path, Qt::PenStyle penStyle);
void PlotSolidLinePath(QTextStream &out, QVector<QPoint> path); void PlotSolidLinePath(QTextStream &out, const QVector<QPoint> &path);
void PlotPathForStyle(QTextStream &out, QVector<QPoint> path, QVector<int> pattern); void PlotPathForStyle(QTextStream &out, QVector<QPoint> path, QVector<int> pattern);
void PlotPainterPath(QTextStream &out, const QPainterPath &path, Qt::PenStyle penStyle); void PlotPainterPath(QTextStream &out, const QPainterPath &path, Qt::PenStyle penStyle);
void PlotCircle(QTextStream &out, const QPointF &center, qreal radius);
void HPPenUp(QTextStream &out, QPoint point); void HPPenUp(QTextStream &out, QPoint point);
void HPPenUp(QTextStream &out); void HPPenUp(QTextStream &out);

View File

@ -639,22 +639,6 @@ auto AngleBySecondRightAngle(QVector<VRawSAPoint> points, QPointF p1, QPointF p2
return points; return points;
} }
//---------------------------------------------------------------------------------------------------------------------
auto SingleParallelPoint(const QPointF &p1, const QPointF &p2, qreal angle, qreal width) -> QPointF
{
QLineF pLine(p1, p2);
pLine.setAngle(pLine.angle() + angle);
pLine.setLength(width);
return pLine.p2();
}
//---------------------------------------------------------------------------------------------------------------------
auto SimpleParallelLine(const QPointF &p1, const QPointF &p2, qreal width) -> QLineF
{
const QLineF paralel = QLineF(SingleParallelPoint(p1, p2, 90, width), SingleParallelPoint(p2, p1, -90, width));
return paralel;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto BisectorLine(const QPointF &p1, const QPointF &p2, const QPointF &p3) -> QLineF auto BisectorLine(const QPointF &p1, const QPointF &p2, const QPointF &p3) -> QLineF
{ {
@ -971,7 +955,7 @@ void VAbstractPiece::SetForbidFlipping(bool value)
if (value) if (value)
{ {
SetForceFlipping(not value); d->m_forceFlipping = not value;
} }
} }
@ -988,7 +972,7 @@ void VAbstractPiece::SetForceFlipping(bool value)
if (value) if (value)
{ {
SetForbidFlipping(not value); d->m_forbidFlipping = not value;
} }
} }
@ -1052,6 +1036,18 @@ void VAbstractPiece::SetSewLineOnDrawing(bool value)
d->m_onDrawing = value; d->m_onDrawing = value;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::IsShowFullPiece() const -> bool
{
return d->m_showFullPiece;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetShowFullPiece(bool value)
{
d->m_showFullPiece = value;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::GetSAWidth() const -> qreal auto VAbstractPiece::GetSAWidth() const -> qreal
{ {
@ -1521,6 +1517,78 @@ void VAbstractPiece::SetPriority(uint value)
d->m_priority = value; d->m_priority = value;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::GetFoldLineType() const -> FoldLineType
{
return d->m_foldLineType;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetFoldLineType(FoldLineType lineType)
{
d->m_foldLineType = lineType;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::GetFoldLineSvgFontSize() const -> unsigned int
{
return d->m_foldLineSvgFontSize;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetFoldLineSvgFontSize(unsigned int size)
{
d->m_foldLineSvgFontSize = size;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::IsFoldLineLabelFontItalic() const -> bool
{
return d->m_foldLineLabelFontItalic;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetFoldLineLabelFontItalic(bool value)
{
d->m_foldLineLabelFontItalic = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::IsFoldLineLabelFontBold() const -> bool
{
return d->m_foldLineLabelFontBold;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetFoldLineLabelFontBold(bool value)
{
d->m_foldLineLabelFontBold = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::GetFoldLineLabel() const -> QString
{
return d->m_foldLineLabel;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetFoldLineLabel(const QString &value)
{
d->m_foldLineLabel = value;
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::GetFoldLineLabelAlignment() const -> int
{
return d->m_foldLineLabelAlignment;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractPiece::SetFoldLineLabelAlignment(int alignment)
{
d->m_foldLineLabelAlignment = alignment;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VAbstractPiece::GetUUID() const -> QUuid auto VAbstractPiece::GetUUID() const -> QUuid
{ {
@ -1953,6 +2021,7 @@ auto VAbstractPiece::PlaceLabelShape(const VLayoutPlaceLabel &label) -> PlaceLab
} }
QVector<VLayoutPoint> shape3; QVector<VLayoutPoint> shape3;
shape3.reserve(points.size());
for (int i = 0; i < points.size(); ++i) for (int i = 0; i < points.size(); ++i)
{ {
bool turnPoint = false; bool turnPoint = false;
@ -1979,6 +2048,7 @@ auto VAbstractPiece::PlaceLabelShape(const VLayoutPlaceLabel &label) -> PlaceLab
} }
QVector<VLayoutPoint> circle; QVector<VLayoutPoint> circle;
circle.reserve(points.size());
for (int i = 0; i < points.size(); ++i) for (int i = 0; i < points.size(); ++i)
{ {
bool turnPoint = false; bool turnPoint = false;

View File

@ -35,9 +35,12 @@
#include <QPointF> #include <QPointF>
#include <QSharedDataPointer> #include <QSharedDataPointer>
#include <QtGlobal> #include <QtGlobal>
#include <algorithm>
#include "../vgeometry/vgeometrydef.h"
#include "../vgeometry/vgobject.h" #include "../vgeometry/vgobject.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/testpath.h"
#include "vrawsapoint.h" #include "vrawsapoint.h"
#include "vsapoint.h" #include "vsapoint.h"
@ -47,6 +50,17 @@ class VGrainlineData;
class VContainer; class VContainer;
class VRawSAPoint; class VRawSAPoint;
class VLayoutPlaceLabel; class VLayoutPlaceLabel;
class VLayoutPoint;
template <typename T> struct IsLayoutPoint
{
static const bool value = false;
};
template <> struct IsLayoutPoint<VLayoutPoint>
{
static const bool value = true;
};
using PlaceLabelImg = QVector<QVector<VLayoutPoint>>; using PlaceLabelImg = QVector<QVector<VLayoutPoint>>;
@ -89,6 +103,9 @@ public:
auto IsSewLineOnDrawing() const -> bool; auto IsSewLineOnDrawing() const -> bool;
void SetSewLineOnDrawing(bool value); void SetSewLineOnDrawing(bool value);
auto IsShowFullPiece() const -> bool;
void SetShowFullPiece(bool value);
auto GetSAWidth() const -> qreal; auto GetSAWidth() const -> qreal;
void SetSAWidth(qreal value); void SetSAWidth(qreal value);
@ -101,6 +118,24 @@ public:
auto GetPriority() const -> uint; auto GetPriority() const -> uint;
void SetPriority(uint value); void SetPriority(uint value);
auto GetFoldLineType() const -> FoldLineType;
void SetFoldLineType(FoldLineType lineType);
auto GetFoldLineSvgFontSize() const -> unsigned int;
void SetFoldLineSvgFontSize(unsigned int size);
auto IsFoldLineLabelFontItalic() const -> bool;
void SetFoldLineLabelFontItalic(bool value);
auto IsFoldLineLabelFontBold() const -> bool;
void SetFoldLineLabelFontBold(bool value);
auto GetFoldLineLabel() const -> QString;
void SetFoldLineLabel(const QString &value);
auto GetFoldLineLabelAlignment() const -> int;
void SetFoldLineLabelAlignment(int alignment);
auto GetUUID() const -> QUuid; auto GetUUID() const -> QUuid;
void SetUUID(const QUuid &uuid); void SetUUID(const QUuid &uuid);
void SetUUID(const QString &uuid); void SetUUID(const QString &uuid);
@ -142,6 +177,22 @@ public:
template <class T> template <class T>
static auto RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true) -> QVector<T>; static auto RemoveDublicates(const QVector<T> &points, bool removeFirstAndLast = true) -> QVector<T>;
template <class T>
static auto SubdividePath(const QVector<T> &boundary, const QPointF &p, QVector<T> &sub1, QVector<T> &sub2) -> bool;
template <class T> static auto MirrorPath(const QVector<T> &points, const QLineF &mirrorLine) -> QVector<T>;
template <class T> static auto FullPath(const QVector<T> &points, const QLineF &mirrorLine) -> QVector<T>;
template <class T>
static auto MapVector(QVector<T> points, const QTransform &matrix, bool mirror = false) -> QVector<T>;
template <class T>
static auto MapPoint(T obj, const QTransform &matrix) -> typename std::enable_if<!IsLayoutPoint<T>::value, T>::type;
template <class T>
static auto MapPoint(T obj, const QTransform &matrix) -> typename std::enable_if<IsLayoutPoint<T>::value, T>::type;
protected: protected:
static auto IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) -> bool; static auto IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint) -> bool;
static auto IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint) -> bool; static auto IsEkvPointOnLine(const VSAPoint &iPoint, const VSAPoint &prevPoint, const VSAPoint &nextPoint) -> bool;
@ -161,6 +212,11 @@ protected:
private: private:
QSharedDataPointer<VAbstractPieceData> d; QSharedDataPointer<VAbstractPieceData> d;
template <typename T>
static auto MakeTurnPoint(const QPointF &p) -> typename std::enable_if<!IsLayoutPoint<T>::value, T>::type;
template <typename T>
static auto MakeTurnPoint(const QPointF &p) -> typename std::enable_if<IsLayoutPoint<T>::value, T>::type;
}; };
Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VAbstractPiece, Q_MOVABLE_TYPE); // NOLINT
@ -694,4 +750,232 @@ inline auto VAbstractPiece::IntersectionPoint<QPointF>(QPointF crosPoint, const
return crosPoint; return crosPoint;
} }
//---------------------------------------------------------------------------------------------------------------------
template <typename T>
inline auto VAbstractPiece::MakeTurnPoint(const QPointF &p) ->
typename std::enable_if<!IsLayoutPoint<T>::value, T>::type
{
return p;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T>
inline auto VAbstractPiece::MakeTurnPoint(const QPointF &p) -> typename std::enable_if<IsLayoutPoint<T>::value, T>::type
{
T breakPoint(p);
breakPoint.SetTurnPoint(true);
return breakPoint;
}
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VAbstractPiece::SubdividePath(const QVector<T> &boundary, const QPointF &p, QVector<T> &sub1,
QVector<T> &sub2) -> bool
{
if (boundary.size() < 2)
{
return false;
}
bool found = false;
sub1.clear();
sub2.clear();
for (qint32 i = 0; i < boundary.count() - 1; ++i)
{
if (found)
{
if (not VFuzzyComparePoints(boundary.at(i), p))
{
sub2.append(boundary.at(i));
}
if (i + 1 == boundary.count() - 1)
{
sub2.append(boundary.at(i + 1));
}
continue;
}
if (!VGObject::IsPointOnLineSegment(p, static_cast<QPointF>(boundary.at(i)),
static_cast<QPointF>(boundary.at(i + 1))))
{
sub1.append(boundary.at(i));
continue;
}
if (not VFuzzyComparePoints(boundary.at(i), p))
{
sub1.append(boundary.at(i));
}
sub1.append(MakeTurnPoint<T>(p));
sub2.append(MakeTurnPoint<T>(p));
if (i + 1 == boundary.count() - 1 && not VFuzzyComparePoints(boundary.at(i + 1), p))
{
sub2.append(boundary.at(i + 1));
}
found = true;
}
if (not found)
{
sub1.clear();
}
return found;
}
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VAbstractPiece::MirrorPath(const QVector<T> &points, const QLineF &mirrorLine) -> QVector<T>
{
QVector<T> flipped;
flipped.reserve(points.size());
const QTransform matrix = VGObject::FlippingMatrix(mirrorLine);
for (const auto &p : points)
{
flipped.append(matrix.map(p));
}
return flipped;
}
//---------------------------------------------------------------------------------------------------------------------
template <>
inline auto VAbstractPiece::MirrorPath<VLayoutPoint>(const QVector<VLayoutPoint> &points, const QLineF &mirrorLine)
-> QVector<VLayoutPoint>
{
QVector<VLayoutPoint> flipped;
flipped.reserve(points.size());
const QTransform matrix = VGObject::FlippingMatrix(mirrorLine);
for (const auto &p : points)
{
VLayoutPoint tmp = p;
QPointF const flippedPoint = matrix.map(static_cast<QPointF>(p));
tmp.setX(flippedPoint.x());
tmp.setY(flippedPoint.y());
flipped.append(tmp);
}
return flipped;
}
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VAbstractPiece::FullPath(const QVector<T> &points, const QLineF &mirrorLine) -> QVector<T>
{
// DumpVector(points, QStringLiteral("input.json.XXXXXX")); // Uncomment for dumping test data
if (mirrorLine.isNull())
{
return points;
}
if (points.size() <= 3)
{
return points;
}
// points = CorrectFullPathInput(points, mirrorLine);
bool closedPath = (points.constFirst() == points.constLast());
bool pathReady = false;
QVector<T> base;
if (VFuzzyComparePoints(points.constFirst(), mirrorLine.p2()))
{
if (closedPath)
{
if (VFuzzyComparePoints(points.at(points.size() - 2), mirrorLine.p1()))
{
base = points;
base.removeLast();
pathReady = true;
}
}
else
{
if (VFuzzyComparePoints(points.constLast(), mirrorLine.p1()))
{
base = points;
pathReady = true;
}
}
}
if (!pathReady)
{
QVector<T> sub1;
QVector<T> sub2;
if (!VAbstractPiece::SubdividePath(points, mirrorLine.p1(), sub1, sub2))
{
return points;
}
QVector<T> reversed = points;
std::reverse(reversed.begin(), reversed.end());
QVector<T> sub3;
QVector<T> sub4;
if (!VAbstractPiece::SubdividePath(reversed, mirrorLine.p2(), sub3, sub4))
{
return points;
}
base = sub3;
std::reverse(base.begin(), base.end());
base += sub1;
pathReady = true;
}
QVector<T> fullPath = MirrorPath(base, mirrorLine);
std::reverse(fullPath.begin(), fullPath.end());
fullPath += base;
// DumpVector(fullPath, QStringLiteral("output.json.XXXXXX")); // Uncomment for dumping test data
return fullPath;
}
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VAbstractPiece::MapVector(QVector<T> points, const QTransform &matrix, bool mirror) -> QVector<T>
{
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const T &point) { return MapPoint(point, matrix); });
if (mirror)
{
std::reverse(points.begin(), points.end());
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T>
auto VAbstractPiece::MapPoint(T obj, const QTransform &matrix) ->
typename std::enable_if<!IsLayoutPoint<T>::value, T>::type
{
return matrix.map(obj);
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T>
auto VAbstractPiece::MapPoint(T obj, const QTransform &matrix) ->
typename std::enable_if<IsLayoutPoint<T>::value, T>::type
{
auto p = matrix.map(obj);
obj.setX(p.x());
obj.setY(p.y());
return obj;
}
#endif // VABSTRACTPIECE_H #endif // VABSTRACTPIECE_H

View File

@ -59,24 +59,33 @@ public:
QString m_name{tr("Detail")}; // NOLINT (misc-non-private-member-variables-in-classes) QString m_name{tr("Detail")}; // NOLINT (misc-non-private-member-variables-in-classes)
/** @brief forbidFlipping forbid piece to be mirrored in a layout. */ /** @brief forbidFlipping forbid piece to be mirrored in a layout. */
bool m_forbidFlipping{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_forbidFlipping{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_forceFlipping{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_forceFlipping{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_followGrainline{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_followGrainline{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_seamAllowance{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_seamAllowance{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_seamAllowanceBuiltIn{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_seamAllowanceBuiltIn{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_hideMainPath{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_hideMainPath{false}; // NOLINT (misc-non-private-member-variables-in-classes)
qreal m_width{0}; // NOLINT (misc-non-private-member-variables-in-classes) qreal m_width{0}; // NOLINT (misc-non-private-member-variables-in-classes)
qreal m_mx{0}; // NOLINT (misc-non-private-member-variables-in-classes) qreal m_mx{0}; // NOLINT (misc-non-private-member-variables-in-classes)
qreal m_my{0}; // NOLINT (misc-non-private-member-variables-in-classes) qreal m_my{0}; // NOLINT (misc-non-private-member-variables-in-classes)
uint m_priority{0}; // NOLINT (misc-non-private-member-variables-in-classes) uint m_priority{0}; // NOLINT (misc-non-private-member-variables-in-classes)
QUuid m_uuid{QUuid::createUuid()}; // NOLINT (misc-non-private-member-variables-in-classes) QUuid m_uuid{QUuid::createUuid()}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_onDrawing{false}; // NOLINT (misc-non-private-member-variables-in-classes) bool m_onDrawing{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_showFullPiece{true}; // NOLINT (misc-non-private-member-variables-in-classes)
unsigned int m_foldLineSvgFontSize{defFoldLineFontSize}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_foldLineLabelFontItalic{false}; // NOLINT (misc-non-private-member-variables-in-classes)
bool m_foldLineLabelFontBold{false}; // NOLINT (misc-non-private-member-variables-in-classes)
QString m_foldLineLabel{}; // NOLINT (misc-non-private-member-variables-in-classes)
int m_foldLineLabelAlignment{Qt::AlignHCenter}; // NOLINT (misc-non-private-member-variables-in-classes)
// NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
FoldLineType m_foldLineType{FoldLineType::TwoArrowsTextAbove};
private: private:
Q_DISABLE_ASSIGN_MOVE(VAbstractPieceData) // NOLINT Q_DISABLE_ASSIGN_MOVE(VAbstractPieceData) // NOLINT
static constexpr quint32 streamHeader = 0x05CDD73A; // CRC-32Q string "VAbstractPieceData" static constexpr quint32 streamHeader = 0x05CDD73A; // CRC-32Q string "VAbstractPieceData"
static constexpr quint16 classVersion = 5; static constexpr quint16 classVersion = 6;
}; };
QT_WARNING_POP QT_WARNING_POP
@ -116,6 +125,15 @@ inline auto operator<<(QDataStream &dataStream, const VAbstractPieceData &piece)
// Added in classVersion = 5 // Added in classVersion = 5
dataStream << piece.m_followGrainline; dataStream << piece.m_followGrainline;
// Added in classVersion = 6
dataStream << piece.m_showFullPiece;
dataStream << piece.m_foldLineSvgFontSize;
dataStream << piece.m_foldLineType;
dataStream << piece.m_foldLineLabelFontItalic;
dataStream << piece.m_foldLineLabelFontBold;
dataStream << piece.m_foldLineLabel;
dataStream << piece.m_foldLineLabelAlignment;
return dataStream; return dataStream;
} }
@ -176,6 +194,17 @@ inline auto operator>>(QDataStream &dataStream, VAbstractPieceData &piece) -> QD
dataStream >> piece.m_followGrainline; dataStream >> piece.m_followGrainline;
} }
if (actualClassVersion >= 6)
{
dataStream >> piece.m_showFullPiece;
dataStream >> piece.m_foldLineSvgFontSize;
dataStream >> piece.m_foldLineType;
dataStream >> piece.m_foldLineLabelFontItalic;
dataStream >> piece.m_foldLineLabelFontBold;
dataStream >> piece.m_foldLineLabel;
dataStream >> piece.m_foldLineLabelAlignment;
}
return dataStream; return dataStream;
} }

View File

@ -30,10 +30,12 @@
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../vgeometry/vgobject.h" #include "../vgeometry/vgobject.h"
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "vabstractpiece.h"
#include "vlayoutpiecepath.h" #include "vlayoutpiecepath.h"
#include <QPoint> #include <QPoint>
#include <QtDebug> #include <QtDebug>
#include <algorithm>
#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
@ -84,211 +86,6 @@ auto PrepareSequenceItem(const QVector<VLayoutPoint> &path, bool drawMode, VBoun
return itemData; return itemData;
} }
//---------------------------------------------------------------------------------------------------------------------
auto PrepareTPassmarkShape(const VLayoutPassmark &passmark, bool drawMode) -> QVector<QVector<VLayoutPoint>>
{
if (passmark.lines.isEmpty())
{
return {};
}
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QLineF line1 = passmark.lines.constFirst();
QVector<VLayoutPoint> shape1;
shape1.append(TurnPoint(line1.p1()));
shape1.append(TurnPoint(line1.p2()));
if (passmark.lines.size() <= 1)
{
return {shape1};
}
const QLineF &line2 = passmark.lines.constLast();
if (!drawMode)
{
shape1.append(TurnPoint(line2.p1()));
shape1.append(TurnPoint(line2.p2()));
shape1.append(TurnPoint(line1.p2()));
return {shape1};
}
QVector<VLayoutPoint> shape2;
shape2.append(TurnPoint(line2.p1()));
shape2.append(TurnPoint(line2.p2()));
return {shape1, shape2};
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareExternalVPassmarkShape(const VLayoutPassmark &passmark, bool drawMode) -> QVector<QVector<VLayoutPoint>>
{
if (passmark.lines.isEmpty())
{
return {};
}
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QLineF line1 = passmark.lines.constFirst();
QVector<VLayoutPoint> shape;
if (!drawMode)
{
shape.append(TurnPoint(line1.p2()));
}
shape.append(TurnPoint(line1.p1()));
shape.append(TurnPoint(line1.p2()));
if (passmark.lines.size() <= 1)
{
return {shape};
}
const QLineF &line2 = passmark.lines.constLast();
shape.append(TurnPoint(line2.p1()));
shape.append(TurnPoint(line2.p2()));
if (!drawMode)
{
shape.append(TurnPoint(line2.p1()));
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareNoneBreakingPassmarkShape(const VLayoutPassmark &passmark) -> QVector<QVector<VLayoutPoint>>
{
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QVector<VLayoutPoint> shape;
shape.reserve(passmark.lines.size() + 1);
for (int i = 0; i < passmark.lines.size(); ++i)
{
const QLineF &line = passmark.lines.at(i);
shape.append(TurnPoint(line.p1()));
if (passmark.lines.size() - 1 == i)
{
shape.append(TurnPoint(line.p2()));
}
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto PrepareUPassmarkShape(const VLayoutPassmark &passmark) -> QVector<QVector<VLayoutPoint>>
{
auto LayoutPoint = [](QPointF point, bool turnPoint, bool curvePoint)
{
VLayoutPoint p(point);
p.SetTurnPoint(turnPoint);
p.SetCurvePoint(curvePoint);
return p;
};
qreal radius = QLineF(passmark.baseLine.p1(), passmark.lines.constFirst().p1()).length();
if (passmark.baseLine.length() - radius > accuracyPointOnLine)
{
QVector<QLineF> lines = passmark.lines;
if (lines.size() < 3)
{
return {};
}
QLineF line1 = lines.takeFirst();
QVector<VLayoutPoint> shape;
shape.reserve(4 + passmark.lines.size() + 1);
shape.append(LayoutPoint(line1.p1(), true, false));
shape.append(LayoutPoint(line1.p2(), true, true));
QLineF line2 = lines.takeLast();
for (int i = 0; i < passmark.lines.size(); ++i)
{
const QLineF &line = passmark.lines.at(i);
shape.append(LayoutPoint(line.p1(), false, true));
if (passmark.lines.size() - 1 == i)
{
shape.append(LayoutPoint(line.p2(), false, true));
}
}
shape.append(LayoutPoint(line2.p1(), true, true));
shape.append(LayoutPoint(line2.p2(), true, false));
return {shape};
}
QVector<VLayoutPoint> shape;
shape.reserve(passmark.lines.size() + 1);
for (int i = 0; i < passmark.lines.size(); ++i)
{
const QLineF &line = passmark.lines.at(i);
shape.append(LayoutPoint(line.p1(), false, true));
if (passmark.lines.size() - 1 == i)
{
shape.append(LayoutPoint(line.p2(), false, true));
}
}
if (!shape.isEmpty())
{
shape.first().SetTurnPoint(true);
shape.last().SetTurnPoint(true);
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto PreparePassmarkShape(const VLayoutPassmark &passmark, bool drawMode) -> QVector<QVector<VLayoutPoint>>
{
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::InternalVMark:
case PassmarkLineType::BoxMark:
case PassmarkLineType::CheckMark:
return PrepareNoneBreakingPassmarkShape(passmark);
case PassmarkLineType::ExternalVMark:
return PrepareExternalVPassmarkShape(passmark, drawMode);
case PassmarkLineType::TMark:
return PrepareTPassmarkShape(passmark, drawMode);
case PassmarkLineType::UMark:
return PrepareUPassmarkShape(passmark);
default:
break;
}
return {};
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void ConvertTwoLinesPassmark(const VLayoutPassmark &passmark, QList<VBoundarySequenceItemData> &notchSequence) void ConvertTwoLinesPassmark(const VLayoutPassmark &passmark, QList<VBoundarySequenceItemData> &notchSequence)
{ {
@ -371,170 +168,6 @@ void ConvertThreeLinesPassmark(const VLayoutPassmark &passmark, QList<VBoundaryS
FillSequance(itemData, notchSequence); FillSequance(itemData, notchSequence);
} }
} }
//---------------------------------------------------------------------------------------------------------------------
auto SubdividePath(const QVector<VLayoutPoint> &boundary, const QPointF &p, QVector<VLayoutPoint> &sub1,
QVector<VLayoutPoint> &sub2) -> bool
{
if (boundary.size() < 2)
{
return false;
}
bool found = false;
sub1.clear();
sub2.clear();
auto BreakPoint = [p]()
{
VLayoutPoint breakPoint(p);
breakPoint.SetTurnPoint(true);
return breakPoint;
};
for (qint32 i = 0; i < boundary.count() - 1; ++i)
{
if (found)
{
sub2.append(boundary.at(i));
if (i + 1 == boundary.count() - 1)
{
sub2.append(boundary.at(i + 1));
}
continue;
}
if (!VGObject::IsPointOnLineSegment(p, static_cast<QPointF>(boundary.at(i)),
static_cast<QPointF>(boundary.at(i + 1))))
{
sub1.append(boundary.at(i));
continue;
}
if (not VFuzzyComparePoints(boundary.at(i), p))
{
sub1.append(boundary.at(i));
sub1.append(BreakPoint());
}
else
{
if (not sub1.isEmpty())
{
sub1.append(BreakPoint());
}
}
if (not VFuzzyComparePoints(boundary.at(i + 1), p))
{
sub2.append(BreakPoint());
if (i + 1 == boundary.count() - 1)
{
sub2.append(boundary.at(i + 1));
}
}
found = true;
}
if (not found)
{
sub1.clear();
}
return found;
}
//---------------------------------------------------------------------------------------------------------------------
auto InsertDisconnect(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) -> bool
{
auto passmark = item.item.value<VLayoutPassmark>();
bool inserted = false;
const auto boundary = sequence.at(i).item.value<VLayoutPiecePath>().Points();
QVector<VLayoutPoint> sub1;
QVector<VLayoutPoint> sub2;
if (!SubdividePath(boundary, passmark.baseLine.p1(), sub1, sub2))
{
return false;
}
sequence.removeAt(i);
if (not sub2.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(sub2, drawMode, VBoundarySequenceItem::Boundary));
}
QVector<QVector<VLayoutPoint>> shape = PreparePassmarkShape(passmark, drawMode);
for (auto &subShape : shape)
{
sequence.insert(i, PrepareSequenceItem(subShape, drawMode, VBoundarySequenceItem::PassmarkShape));
}
if (not sub1.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(sub1, drawMode, VBoundarySequenceItem::Boundary));
}
inserted = true;
return inserted;
}
//---------------------------------------------------------------------------------------------------------------------
auto InsertCutOut(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) -> bool
{
auto passmark = item.item.value<VLayoutPassmark>();
QVector<QVector<VLayoutPoint>> shape = PreparePassmarkShape(passmark, drawMode);
if (shape.isEmpty())
{
return false;
}
const QVector<VLayoutPoint> &subShape = shape.constFirst();
if (subShape.size() < 2)
{
return false;
}
const auto boundary = sequence.at(i).item.value<VLayoutPiecePath>().Points();
QVector<VLayoutPoint> startSub1;
QVector<VLayoutPoint> startSub2;
if (!SubdividePath(boundary, subShape.constFirst(), startSub1, startSub2))
{
return false;
}
QVector<VLayoutPoint> endSub1;
QVector<VLayoutPoint> endSub2;
if (!SubdividePath(boundary, subShape.constLast(), endSub1, endSub2))
{
return false;
}
sequence.removeAt(i);
if (not endSub2.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(endSub2, drawMode, VBoundarySequenceItem::Boundary));
}
sequence.insert(i, PrepareSequenceItem(subShape, drawMode, VBoundarySequenceItem::PassmarkShape));
if (not startSub1.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(startSub1, drawMode, VBoundarySequenceItem::Boundary));
}
return true;
}
} // namespace } // namespace
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -585,6 +218,16 @@ auto VBoundary::Combine(const QVector<VLayoutPassmark> &passmarks, bool drawMode
if (item.type == VBoundarySequenceItem::Passmark) if (item.type == VBoundarySequenceItem::Passmark)
{ {
InsertPassmark(item, sequence, drawMode); InsertPassmark(item, sequence, drawMode);
if (!m_mirrorLine.isNull())
{
auto passmark = item.item.value<VLayoutPassmark>();
if (!VGObject::IsPointOnLineviaPDP(passmark.baseLine.p1(), m_mirrorLine.p1(), m_mirrorLine.p2()))
{
item.mirror = true;
InsertPassmark(item, sequence, drawMode);
}
}
} }
} }
@ -680,3 +323,369 @@ void VBoundary::InsertPassmark(const VBoundarySequenceItemData &item, QList<VBou
: qWarning() << VAbstractApplication::warningMessageSignature + errorMsg; : qWarning() << VAbstractApplication::warningMessageSignature + errorMsg;
} }
} }
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::InsertDisconnect(QList<VBoundarySequenceItemData> &sequence, int i,
const VBoundarySequenceItemData &item, bool drawMode) const -> bool
{
auto passmark = item.item.value<VLayoutPassmark>();
bool inserted = false;
const auto boundary = sequence.at(i).item.value<VLayoutPiecePath>().Points();
QPointF connectionPoint = passmark.baseLine.p1();
if (item.mirror && !m_mirrorLine.isNull())
{
const QTransform matrix = VGObject::FlippingMatrix(m_mirrorLine);
connectionPoint = matrix.map(connectionPoint);
}
QVector<VLayoutPoint> sub1;
QVector<VLayoutPoint> sub2;
if (!VAbstractPiece::SubdividePath(boundary, connectionPoint, sub1, sub2))
{
return false;
}
sequence.removeAt(i);
if (not sub2.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(sub2, drawMode, VBoundarySequenceItem::Boundary));
}
QVector<QVector<VLayoutPoint>> shape = PreparePassmarkShape(passmark, drawMode, item.mirror);
for (auto &subShape : shape)
{
sequence.insert(i, PrepareSequenceItem(subShape, drawMode, VBoundarySequenceItem::PassmarkShape));
}
if (not sub1.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(sub1, drawMode, VBoundarySequenceItem::Boundary));
}
inserted = true;
return inserted;
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::InsertCutOut(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) const -> bool
{
auto passmark = item.item.value<VLayoutPassmark>();
QVector<QVector<VLayoutPoint>> shape = PreparePassmarkShape(passmark, drawMode, item.mirror);
if (shape.isEmpty())
{
return false;
}
const QVector<VLayoutPoint> &subShape = shape.constFirst();
if (subShape.size() < 2)
{
return false;
}
const auto boundary = sequence.at(i).item.value<VLayoutPiecePath>().Points();
QVector<VLayoutPoint> startSub1;
QVector<VLayoutPoint> startSub2;
if (!VAbstractPiece::SubdividePath(boundary, subShape.constFirst(), startSub1, startSub2))
{
return false;
}
QVector<VLayoutPoint> endSub1;
QVector<VLayoutPoint> endSub2;
if (!VAbstractPiece::SubdividePath(boundary, subShape.constLast(), endSub1, endSub2))
{
return false;
}
sequence.removeAt(i);
if (not endSub2.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(endSub2, drawMode, VBoundarySequenceItem::Boundary));
}
sequence.insert(i, PrepareSequenceItem(subShape, drawMode, VBoundarySequenceItem::PassmarkShape));
if (not startSub1.isEmpty())
{
sequence.insert(i, PrepareSequenceItem(startSub1, drawMode, VBoundarySequenceItem::Boundary));
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::PreparePassmarkShape(const VLayoutPassmark &passmark, bool drawMode, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>
{
switch (passmark.type)
{
case PassmarkLineType::OneLine:
case PassmarkLineType::InternalVMark:
case PassmarkLineType::BoxMark:
case PassmarkLineType::CheckMark:
return PrepareNoneBreakingPassmarkShape(passmark, mirrorNotch);
case PassmarkLineType::ExternalVMark:
return PrepareExternalVPassmarkShape(passmark, drawMode, mirrorNotch);
case PassmarkLineType::TMark:
return PrepareTPassmarkShape(passmark, drawMode, mirrorNotch);
case PassmarkLineType::UMark:
return PrepareUPassmarkShape(passmark, mirrorNotch);
default:
break;
}
return {};
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::PrepareNoneBreakingPassmarkShape(const VLayoutPassmark &passmark, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>
{
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QVector<QLineF> lines = passmark.lines;
if (mirrorNotch && !m_mirrorLine.isNull())
{
const QTransform matrix = VGObject::FlippingMatrix(m_mirrorLine);
lines = VAbstractPiece::MapVector(lines, matrix);
}
QVector<VLayoutPoint> shape;
shape.reserve(lines.size() + 1);
for (int i = 0; i < lines.size(); ++i)
{
const QLineF &line = lines.at(i);
shape.append(TurnPoint(line.p1()));
if (lines.size() - 1 == i)
{
shape.append(TurnPoint(line.p2()));
}
}
if (mirrorNotch && !m_mirrorLine.isNull() &&
(passmark.type == PassmarkLineType::InternalVMark || passmark.type == PassmarkLineType::BoxMark ||
passmark.type == PassmarkLineType::CheckMark))
{
std::reverse(shape.begin(), shape.end());
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::PrepareExternalVPassmarkShape(const VLayoutPassmark &passmark, bool drawMode, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>
{
if (passmark.lines.isEmpty())
{
return {};
}
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QVector<QLineF> lines = passmark.lines;
if (mirrorNotch && !m_mirrorLine.isNull())
{
const QTransform matrix = VGObject::FlippingMatrix(m_mirrorLine);
lines = VAbstractPiece::MapVector(lines, matrix);
}
QLineF line1 = lines.constFirst();
QVector<VLayoutPoint> shape;
if (!drawMode)
{
shape.append(TurnPoint(line1.p2()));
}
shape.append(TurnPoint(line1.p1()));
shape.append(TurnPoint(line1.p2()));
if (lines.size() <= 1)
{
return {shape};
}
const QLineF &line2 = lines.constLast();
shape.append(TurnPoint(line2.p1()));
shape.append(TurnPoint(line2.p2()));
if (!drawMode)
{
shape.append(TurnPoint(line2.p1()));
if (mirrorNotch && !m_mirrorLine.isNull())
{
std::reverse(shape.begin(), shape.end());
}
}
return {shape};
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::PrepareTPassmarkShape(const VLayoutPassmark &passmark, bool drawMode, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>
{
if (passmark.lines.isEmpty())
{
return {};
}
auto TurnPoint = [](QPointF point)
{
VLayoutPoint p(point);
p.SetTurnPoint(true);
return p;
};
QVector<QLineF> lines = passmark.lines;
if (mirrorNotch && !m_mirrorLine.isNull())
{
const QTransform matrix = VGObject::FlippingMatrix(m_mirrorLine);
lines = VAbstractPiece::MapVector(lines, matrix);
}
QLineF line1 = lines.constFirst();
QVector<VLayoutPoint> shape1;
shape1.append(TurnPoint(line1.p1()));
shape1.append(TurnPoint(line1.p2()));
if (lines.size() <= 1)
{
return {shape1};
}
const QLineF &line2 = lines.constLast();
if (!drawMode)
{
shape1.append(TurnPoint(line2.p1()));
shape1.append(TurnPoint(line2.p2()));
shape1.append(TurnPoint(line1.p2()));
if (mirrorNotch && !m_mirrorLine.isNull())
{
std::reverse(shape1.begin(), shape1.end());
}
return {shape1};
}
QVector<VLayoutPoint> shape2;
shape2.append(TurnPoint(line2.p1()));
shape2.append(TurnPoint(line2.p2()));
return {shape1, shape2};
}
//---------------------------------------------------------------------------------------------------------------------
auto VBoundary::PrepareUPassmarkShape(const VLayoutPassmark &passmark, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>
{
auto LayoutPoint = [](QPointF point, bool turnPoint, bool curvePoint)
{
VLayoutPoint p(point);
p.SetTurnPoint(turnPoint);
p.SetCurvePoint(curvePoint);
return p;
};
if (passmark.lines.isEmpty())
{
return {};
}
qreal radius = QLineF(passmark.baseLine.p1(), passmark.lines.constFirst().p1()).length();
QVector<QLineF> lines = passmark.lines;
if (mirrorNotch && !m_mirrorLine.isNull())
{
const QTransform matrix = VGObject::FlippingMatrix(m_mirrorLine);
lines = VAbstractPiece::MapVector(lines, matrix);
}
if (passmark.baseLine.length() - radius > accuracyPointOnLine)
{
if (lines.size() < 3)
{
return {};
}
QLineF line1 = lines.takeFirst();
QVector<VLayoutPoint> shape;
shape.reserve(4 + passmark.lines.size() + 1);
shape.append(LayoutPoint(line1.p1(), true, false));
shape.append(LayoutPoint(line1.p2(), true, true));
QLineF line2 = lines.takeLast();
for (int i = 0; i < lines.size(); ++i)
{
const QLineF &line = lines.at(i);
shape.append(LayoutPoint(line.p1(), false, true));
if (lines.size() - 1 == i)
{
shape.append(LayoutPoint(line.p2(), false, true));
}
}
shape.append(LayoutPoint(line2.p1(), true, true));
shape.append(LayoutPoint(line2.p2(), true, false));
if (mirrorNotch && !m_mirrorLine.isNull())
{
std::reverse(shape.begin(), shape.end());
}
return {shape};
}
QVector<VLayoutPoint> shape;
shape.reserve(lines.size() + 1);
for (int i = 0; i < lines.size(); ++i)
{
const QLineF &line = lines.at(i);
shape.append(LayoutPoint(line.p1(), false, true));
if (lines.size() - 1 == i)
{
shape.append(LayoutPoint(line.p2(), false, true));
}
}
if (!shape.isEmpty())
{
shape.first().SetTurnPoint(true);
shape.last().SetTurnPoint(true);
}
if (mirrorNotch && !m_mirrorLine.isNull())
{
std::reverse(shape.begin(), shape.end());
}
return {shape};
}

View File

@ -50,6 +50,7 @@ struct VBoundarySequenceItemData
int number{0}; int number{0};
VBoundarySequenceItem type{VBoundarySequenceItem::Unknown}; VBoundarySequenceItem type{VBoundarySequenceItem::Unknown};
QVariant item{}; QVariant item{};
bool mirror{false};
}; };
class VBoundary class VBoundary
@ -63,17 +64,35 @@ public:
-> QList<VBoundarySequenceItemData>; -> QList<VBoundarySequenceItemData>;
void SetPieceName(const QString &newPieceName); void SetPieceName(const QString &newPieceName);
void SetMirrorLine(const QLineF &newMirrorLine);
private: private:
QVector<VLayoutPoint> m_boundary; QVector<VLayoutPoint> m_boundary;
bool m_seamAllowance; bool m_seamAllowance;
bool m_builtInSeamAllowance; bool m_builtInSeamAllowance;
QString m_pieceName{}; QString m_pieceName{};
QLineF m_mirrorLine{};
auto SkipPassmark(const VLayoutPassmark &passmark, bool layoutAllowance) const -> bool; auto SkipPassmark(const VLayoutPassmark &passmark, bool layoutAllowance) const -> bool;
void InsertPassmark(const VBoundarySequenceItemData &item, QList<VBoundarySequenceItemData> &sequence, void InsertPassmark(const VBoundarySequenceItemData &item, QList<VBoundarySequenceItemData> &sequence,
bool drawMode) const; bool drawMode) const;
auto InsertDisconnect(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) const -> bool;
auto InsertCutOut(QList<VBoundarySequenceItemData> &sequence, int i, const VBoundarySequenceItemData &item,
bool drawMode) const -> bool;
auto PreparePassmarkShape(const VLayoutPassmark &passmark, bool drawMode, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>;
auto PrepareNoneBreakingPassmarkShape(const VLayoutPassmark &passmark, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>;
auto PrepareExternalVPassmarkShape(const VLayoutPassmark &passmark, bool drawMode, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>;
auto PrepareTPassmarkShape(const VLayoutPassmark &passmark, bool drawMode, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>;
auto PrepareUPassmarkShape(const VLayoutPassmark &passmark, bool mirrorNotch) const
-> QVector<QVector<VLayoutPoint>>;
}; };
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -82,4 +101,10 @@ inline void VBoundary::SetPieceName(const QString &newPieceName)
m_pieceName = newPieceName; m_pieceName = newPieceName;
} }
//---------------------------------------------------------------------------------------------------------------------
inline void VBoundary::SetMirrorLine(const QLineF &newMirrorLine)
{
m_mirrorLine = newMirrorLine;
}
#endif // VBOUNDARY_H #endif // VBOUNDARY_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,156 @@
/************************************************************************
**
** @file vfoldline.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 20 12, 2023
**
** @brief
** @copyright
** This source code is part of the Valentina project, a pattern making
** program, whose allow create and modeling patterns of clothing.
** Copyright (C) 2023 Valentina project
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
**
** Valentina is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** Valentina is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef VFOLDLINE_H
#define VFOLDLINE_H
#include <QCoreApplication>
#include <QFont>
#include <QLineF>
#include <QTransform>
#include "../vmisc/def.h"
class QPainterPath;
class VSvgFontEngine;
class QGraphicsSimpleTextItem;
struct TextPosData
{
qreal labelWidth{0};
qreal labelHeight{0};
QLineF base{};
};
struct ArrowsTextPosData : public TextPosData
{
qreal arrowsWidth{0};
qreal arrowsHeight{0};
};
struct ThreeDotsPosData
{
qreal width{0};
qreal defHeight{0};
qreal height{0};
qreal radius{0};
qreal margin{0};
};
struct FoldLabelPosData
{
QFont font{};
QPointF pos{};
QString label{};
qreal angle{0};
};
class VFoldLine
{
Q_DECLARE_TR_FUNCTIONS(VFoldLine) // NOLINT
public:
VFoldLine(const QLineF &line, FoldLineType type);
void SetHeight(qreal newHeight);
void SetWidth(qreal newWidth);
void SetCenterPosition(qreal newCenter);
void SetLabel(const QString &newLabel);
void SetLabelSvgFontSize(unsigned int newFontSize);
void SetLabelFontItalic(bool newItalic);
void SetLabelFontBold(bool newBold);
void SetLabelAlignment(int alignment);
void SetMatrix(const QTransform &matrix);
void SetVerticallyFlipped(bool value);
void SetHorizontallyFlipped(bool value);
void SetXScale(qreal xs);
void SetYScale(qreal ys);
void SetOutlineFont(const QFont &font);
void SetSvgFont(const QString &font);
auto FoldLinePath() const -> QVector<QPainterPath>;
auto FoldLineMarkPoints() const -> QVector<QVector<QPointF>>;
auto LabelPosition(bool &ok) const -> FoldLabelPosData;
void UpdateFoldLineLabel(QGraphicsSimpleTextItem *item) const;
auto ThreeDotsRadius() const -> qreal;
static auto DefaultFoldLineLabel() -> QString;
private:
QLineF m_foldLine{};
FoldLineType m_type{FoldLineType::TwoArrowsTextAbove};
qreal m_height{0};
qreal m_width{0};
qreal m_center{0.5};
QString m_label{};
unsigned int m_svgFontSize{defFoldLineFontSize};
bool m_italic{false};
bool m_bold{false};
int m_alignment{Qt::AlignHCenter};
QTransform m_matrix{};
bool m_verticallyFlipped{false};
bool m_horizontallyFlipped{false};
qreal m_xScale{1.0};
qreal m_yScale{1.0};
QFont m_outlineFont{};
QString m_svgFont{};
auto FoldLineTwoArrowsPath() const -> QVector<QPainterPath>;
auto FoldLineTwoArrowsTextAbovePath() const -> QVector<QPainterPath>;
auto FoldLineTwoArrowsTextUnderPath() const -> QVector<QPainterPath>;
auto FoldLineTextPath() const -> QVector<QPainterPath>;
auto FoldLineThreeDotsPath() const -> QVector<QPainterPath>;
auto FoldLineThreeXPath() const -> QVector<QPainterPath>;
auto TrueCenter(const QLineF &base, qreal width) const -> QPointF;
auto FoldLineLabel() const -> QString;
auto OutlineFontLabel(const QLineF &base, qreal width, qreal textHeight) const -> QPainterPath;
auto SVGFontLabel(const QLineF &base, qreal width, qreal textHeight) const -> QPainterPath;
auto LabelTextHeight() const -> qreal;
auto LabelSVGFontEngine(VSvgFontEngine &engine) const -> bool;
auto LabelOutlineFont() const -> QFont;
auto TwoArrowsPath(qreal width, qreal height) const -> QPainterPath;
auto TwoArrowsPoints(qreal width, qreal height) const -> QVector<QVector<QPointF>>;
auto ThreeDotsPoints() const -> QVector<QVector<QPointF>>;
auto ThreeXPoints() const -> QVector<QVector<QPointF>>;
auto TwoArrowsData() const -> ArrowsTextPosData;
auto TwoArrowsTextAboveData() const -> ArrowsTextPosData;
auto TwoArrowsTextUnderData() const -> ArrowsTextPosData;
auto TextData() const -> TextPosData;
auto ThreeDotsData() const -> ThreeDotsPosData;
};
#endif // VFOLDLINE_H

View File

@ -66,3 +66,15 @@ void VGraphicsFillItem::paint(QPainter *painter, const QStyleOptionGraphicsItem
painter->drawPath(path()); painter->drawPath(path());
painter->restore(); painter->restore();
} }
//---------------------------------------------------------------------------------------------------------------------
VGraphicsFoldLineItem::VGraphicsFoldLineItem(QGraphicsItem *parent)
: VGraphicsFillItem(parent)
{
}
//---------------------------------------------------------------------------------------------------------------------
VGraphicsFoldLineItem::VGraphicsFoldLineItem(const QPainterPath &path, QGraphicsItem *parent)
: VGraphicsFillItem(path, parent)
{
}

View File

@ -97,4 +97,22 @@ inline void VGraphicsFillItem::SetCustomPen(bool newCustomPen)
{ {
m_customPen = newCustomPen; m_customPen = newCustomPen;
} }
class VGraphicsFoldLineItem : public VGraphicsFillItem
{
public:
explicit VGraphicsFoldLineItem(QGraphicsItem *parent = nullptr);
explicit VGraphicsFoldLineItem(const QPainterPath &path, QGraphicsItem *parent = nullptr);
~VGraphicsFoldLineItem() override = default;
auto type() const -> int override { return Type; }
enum
{
Type = UserType + static_cast<int>(Layout::FoldLineItem)
};
private:
Q_DISABLE_COPY_MOVE(VGraphicsFoldLineItem) // NOLINT
};
#endif // VGRAPHICSFILLITEM_H #endif // VGRAPHICSFILLITEM_H

View File

@ -31,7 +31,8 @@ HEADERS += \
$$PWD/vlayoutpiecepath_p.h \ $$PWD/vlayoutpiecepath_p.h \
$$PWD/vbestsquare_p.h \ $$PWD/vbestsquare_p.h \
$$PWD/vrawsapoint.h \ $$PWD/vrawsapoint.h \
$$PWD/vboundary.h $$PWD/vboundary.h \
$$PWD/vfoldline.h
SOURCES += \ SOURCES += \
$$PWD/vlayoutexporter.cpp \ $$PWD/vlayoutexporter.cpp \
@ -52,6 +53,7 @@ SOURCES += \
$$PWD/vlayoutpiece.cpp \ $$PWD/vlayoutpiece.cpp \
$$PWD/vlayoutpiecepath.cpp \ $$PWD/vlayoutpiecepath.cpp \
$$PWD/vrawsapoint.cpp \ $$PWD/vrawsapoint.cpp \
$$PWD/vboundary.cpp $$PWD/vboundary.cpp \
$$PWD/vfoldline.cpp
*msvc*:SOURCES += $$PWD/stable.cpp *msvc*:SOURCES += $$PWD/stable.cpp

View File

@ -57,7 +57,9 @@ VLib {
"vlayoutpiecepath.cpp", "vlayoutpiecepath.cpp",
"vrawsapoint.cpp", "vrawsapoint.cpp",
"vboundary.h", "vboundary.h",
"vboundary.cpp" "vboundary.cpp",
"vfoldline.h",
"vfoldline.cpp"
]; ];
if (Qt.core.versionMajor >= 5 && Qt.core.versionMinor < 12) { if (Qt.core.versionMajor >= 5 && Qt.core.versionMinor < 12) {

View File

@ -52,11 +52,12 @@
#include "../vgeometry/vlayoutplacelabel.h" #include "../vgeometry/vlayoutplacelabel.h"
#include "../vgeometry/vplacelabelitem.h" #include "../vgeometry/vplacelabelitem.h"
#include "../vgeometry/vpointf.h" #include "../vgeometry/vpointf.h"
#include "../vlayout/vabstractpiece.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/def.h"
#include "../vmisc/literals.h" #include "../vmisc/literals.h"
#include "../vmisc/svgfont/vsvgfontdatabase.h" #include "../vmisc/svgfont/vsvgfontdatabase.h"
#include "../vmisc/svgfont/vsvgfontengine.h" #include "../vmisc/svgfont/vsvgfontengine.h"
#include "../vmisc/testpath.h"
#include "../vmisc/vabstractvalapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vpatterndb/calculator.h" #include "../vpatterndb/calculator.h"
#include "../vpatterndb/floatItemData/vgrainlinedata.h" #include "../vpatterndb/floatItemData/vgrainlinedata.h"
@ -64,10 +65,14 @@
#include "../vpatterndb/floatItemData/vpiecelabeldata.h" #include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "../vpatterndb/variables/vmeasurement.h" #include "../vpatterndb/variables/vmeasurement.h"
#include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vcontainer.h"
#include "../vpatterndb/vformula.h"
#include "../vpatterndb/vpassmark.h" #include "../vpatterndb/vpassmark.h"
#include "../vpatterndb/vpiecenode.h" #include "../vpatterndb/vpiecenode.h"
#include "../vwidgets/vpiecegrainline.h" #include "../vwidgets/vpiecegrainline.h"
#include "vabstractpiece.h"
#include "vboundary.h" #include "vboundary.h"
#include "vcommonsettings.h"
#include "vfoldline.h"
#include "vgraphicsfillitem.h" #include "vgraphicsfillitem.h"
#include "vlayoutpiece_p.h" #include "vlayoutpiece_p.h"
#include "vtextmanager.h" #include "vtextmanager.h"
@ -95,6 +100,7 @@ auto ConvertInternalPaths(const VPiece &piece, const VContainer *pattern) -> QVe
VLayoutPiecePath convertedPath(path.PathPoints(pattern, cuttingPath)); VLayoutPiecePath convertedPath(path.PathPoints(pattern, cuttingPath));
convertedPath.SetCutPath(path.IsCutPath()); convertedPath.SetCutPath(path.IsCutPath());
convertedPath.SetPenStyle(path.GetPenType()); convertedPath.SetPenStyle(path.GetPenType());
convertedPath.SetNotMirrored(path.IsNotMirrored());
paths.append(convertedPath); paths.append(convertedPath);
} }
} }
@ -468,6 +474,70 @@ auto PrepareGradationId(const QString &label, const VContainer *pattern) -> QStr
const QMap<QString, QString> placeholders = PrepareGradationPlaceholders(pattern); const QMap<QString, QString> placeholders = PrepareGradationPlaceholders(pattern);
return ReplacePlaceholders(placeholders, label); return ReplacePlaceholders(placeholders, label);
} }
//---------------------------------------------------------------------------------------------------------------------
void InitFoldLine(VLayoutPiece &det, const VPiece &piece, const VContainer *pattern)
{
det.SetFoldLineType(piece.GetFoldLineType());
if (piece.GetFoldLineType() == FoldLineType::None)
{
return;
}
det.SetFoldLineSvgFontSize(piece.GetFoldLineSvgFontSize());
det.SetFoldLineLabelFontItalic(piece.IsFoldLineLabelFontItalic());
det.SetFoldLineLabelFontBold(piece.IsFoldLineLabelFontBold());
det.SetFoldLineLabel(piece.GetFoldLineLabel());
det.SetFoldLineLabelAlignment(piece.GetFoldLineLabelAlignment());
{
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
QFont font = settings->GetLabelFont();
font.setPointSize(static_cast<int>(piece.GetFoldLineSvgFontSize()));
det.SetFoldLineOutlineFont(font);
det.SetFoldLineSVGFontFamily(settings->GetLabelSVGFont());
}
if (piece.IsManualFoldHeight())
{
VFormula formula(piece.GetFormulaFoldHeight(), pattern);
formula.setCheckZero(false);
formula.setCheckLessThanZero(true);
formula.Eval();
if (!formula.error())
{
det.SetFoldLineHeight(ToPixel(formula.getDoubleValue(), *pattern->GetPatternUnit()));
}
}
if (piece.IsManualFoldWidth())
{
VFormula formula(piece.GetFormulaFoldWidth(), pattern);
formula.setCheckZero(false);
formula.setCheckLessThanZero(true);
formula.Eval();
if (!formula.error())
{
det.SetFoldLineWidth(ToPixel(formula.getDoubleValue(), *pattern->GetPatternUnit()));
}
}
if (piece.IsManualFoldCenter())
{
VFormula formula(piece.GetFormulaFoldCenter(), pattern);
formula.setCheckZero(false);
formula.setCheckLessThanZero(true);
formula.Eval();
if (!formula.error())
{
det.SetFoldLineCenterPosition(formula.getDoubleValue());
}
}
}
} // namespace } // namespace
// Friend functions // Friend functions
@ -557,16 +627,26 @@ VLayoutPiece::~VLayoutPiece() = default;
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pattern) -> VLayoutPiece auto VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pattern) -> VLayoutPiece
{ {
QFuture<QVector<VLayoutPoint>> futureSeamAllowance = QFuture<QVector<VLayoutPoint>> const futureSeamAllowance = QtConcurrent::run(
QtConcurrent::run([piece, pattern]() { return piece.SeamAllowancePoints(pattern); }); [piece, pattern]()
QFuture<bool> futureSeamAllowanceValid = {
if (!piece.SeamMirrorLine(pattern).isNull())
{
VPiece tmp = piece;
tmp.SetShowFullPiece(false);
return tmp.SeamAllowancePoints(pattern);
}
return piece.SeamAllowancePoints(pattern);
});
QFuture<bool> const futureSeamAllowanceValid =
QtConcurrent::run([piece, pattern]() { return piece.IsSeamAllowanceValid(pattern); }); QtConcurrent::run([piece, pattern]() { return piece.IsSeamAllowanceValid(pattern); });
QFuture<QVector<VLayoutPoint>> futureMainPath = QFuture<QVector<VLayoutPoint>> const futureMainPath =
QtConcurrent::run([piece, pattern]() { return piece.MainPathPoints(pattern); }); QtConcurrent::run([piece, pattern]() { return piece.MainPathPoints(pattern); });
QFuture<QVector<VLayoutPiecePath>> futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern); QFuture<QVector<VLayoutPiecePath>> const futureInternalPaths =
QFuture<QVector<VLayoutPassmark>> futurePassmarks = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
QFuture<QVector<VLayoutPassmark>> const futurePassmarks =
QtConcurrent::run(VLayoutPiece::ConvertPassmarks, piece, pattern); QtConcurrent::run(VLayoutPiece::ConvertPassmarks, piece, pattern);
QFuture<QVector<VLayoutPlaceLabel>> futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern); QFuture<QVector<VLayoutPlaceLabel>> const futurePlaceLabels = QtConcurrent::run(ConvertPlaceLabels, piece, pattern);
VLayoutPiece det; VLayoutPiece det;
@ -582,6 +662,9 @@ auto VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pat
det.SetForceFlipping(piece.IsForceFlipping()); det.SetForceFlipping(piece.IsForceFlipping());
det.SetFollowGrainline(piece.IsFollowGrainline()); det.SetFollowGrainline(piece.IsFollowGrainline());
det.SetSewLineOnDrawing(piece.IsSewLineOnDrawing()); det.SetSewLineOnDrawing(piece.IsSewLineOnDrawing());
det.SetShowFullPiece(piece.IsShowFullPiece());
det.SetSeamMirrorLine(piece.SeamMirrorLine(pattern));
det.SetSeamAllowanceMirrorLine(piece.SeamAllowanceMirrorLine(pattern));
det.SetId(id); det.SetId(id);
if (not futureSeamAllowanceValid.result()) if (not futureSeamAllowanceValid.result())
@ -626,6 +709,8 @@ auto VLayoutPiece::Create(const VPiece &piece, vidtype id, const VContainer *pat
det.SetGrainline(grainlineGeom, pattern); det.SetGrainline(grainlineGeom, pattern);
} }
InitFoldLine(det, piece, pattern);
return det; return det;
} }
@ -648,8 +733,7 @@ auto VLayoutPiece::Map<VLayoutPassmark>(QVector<VLayoutPassmark> passmarks) cons
{ {
for (auto &passmark : passmarks) for (auto &passmark : passmarks)
{ {
passmark.lines = Map(passmark.lines); passmark = MapPassmark(passmark, d->m_matrix, d->m_verticallyFlipped || d->m_horizontallyFlipped);
passmark.baseLine = d->m_matrix.map(passmark.baseLine);
} }
return passmarks; return passmarks;
@ -659,14 +743,7 @@ auto VLayoutPiece::Map<VLayoutPassmark>(QVector<VLayoutPassmark> passmarks) cons
template <> auto VLayoutPiece::Map<VLayoutPoint>(QVector<VLayoutPoint> points) const -> QVector<VLayoutPoint> template <> auto VLayoutPiece::Map<VLayoutPoint>(QVector<VLayoutPoint> points) const -> QVector<VLayoutPoint>
{ {
std::transform(points.begin(), points.end(), points.begin(), std::transform(points.begin(), points.end(), points.begin(),
[this](VLayoutPoint point) [this](const VLayoutPoint &point) { return MapPoint(point, d->m_matrix); });
{
auto p = static_cast<QPointF>(point); // NOLINT(cppcoreguidelines-slicing)
p = d->m_matrix.map(p);
point.rx() = p.x();
point.ry() = p.y();
return point;
});
if (d->m_verticallyFlipped || d->m_horizontallyFlipped) if (d->m_verticallyFlipped || d->m_horizontallyFlipped)
{ {
std::reverse(points.begin(), points.end()); std::reverse(points.begin(), points.end());
@ -694,6 +771,30 @@ auto VLayoutPiece::GetMappedContourPoints() const -> QVector<VLayoutPoint>
return Map(d->m_contour); return Map(d->m_contour);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetMappedFullContourPoints() const -> QVector<VLayoutPoint>
{
return Map(GetFullContourPoints());
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFullContourPoints() const -> QVector<VLayoutPoint>
{
QVector<VLayoutPoint> points;
points.reserve(d->m_contour.size());
if (!d->m_seamMirrorLine.isNull() && IsShowFullPiece())
{
points = VAbstractPiece::FullPath(d->m_contour, d->m_seamMirrorLine);
points = CheckLoops(CorrectEquidistantPoints(points)); // A path can contains loops
}
else
{
points = d->m_contour;
}
return points;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetContourPoints() const -> QVector<VLayoutPoint> auto VLayoutPiece::GetContourPoints() const -> QVector<VLayoutPoint>
{ {
@ -714,6 +815,30 @@ auto VLayoutPiece::GetMappedSeamAllowancePoints() const -> QVector<VLayoutPoint>
return Map(d->m_seamAllowance); return Map(d->m_seamAllowance);
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetMappedFullSeamAllowancePoints() const -> QVector<VLayoutPoint>
{
return Map(GetFullSeamAllowancePoints());
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFullSeamAllowancePoints() const -> QVector<VLayoutPoint>
{
QVector<VLayoutPoint> points;
points.reserve(d->m_seamAllowance.size());
if (!d->m_seamAllowanceMirrorLine.isNull() && IsShowFullPiece())
{
points = VAbstractPiece::FullPath(d->m_seamAllowance, d->m_seamAllowanceMirrorLine);
points = CheckLoops(CorrectEquidistantPoints(points)); // A path can contains loops
}
else
{
points = d->m_seamAllowance;
}
return points;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetSeamAllowancePoints() const -> QVector<VLayoutPoint> auto VLayoutPiece::GetSeamAllowancePoints() const -> QVector<VLayoutPoint>
{ {
@ -753,17 +878,6 @@ auto VLayoutPiece::GetLayoutAllowancePoints() const -> QVector<QPointF>
return d->m_layoutAllowance; return d->m_layoutAllowance;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPieceTextPosition() const -> QPointF
{
if (d->m_detailLabel.count() > 2)
{
return d->m_matrix.map(d->m_detailLabel.constFirst());
}
return {};
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPieceText() const -> QStringList auto VLayoutPiece::GetPieceText() const -> QStringList
{ {
@ -837,17 +951,6 @@ void VLayoutPiece::SetPieceLabelData(const VTextManager &data)
d->m_tmDetail = data; d->m_tmDetail = data;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPatternTextPosition() const -> QPointF
{
if (d->m_patternInfo.count() > 2)
{
return d->m_matrix.map(d->m_patternInfo.constFirst());
}
return {};
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetPatternText() const -> QStringList auto VLayoutPiece::GetPatternText() const -> QStringList
{ {
@ -919,6 +1022,102 @@ void VLayoutPiece::SetPatternLabelData(const VTextManager &data)
d->m_tmPattern = data; d->m_tmPattern = data;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetMappedSeamMirrorLine() const -> QLineF
{
return d->m_matrix.map(d->m_seamMirrorLine);
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetSeamMirrorLine() const -> QLineF
{
return d->m_seamMirrorLine;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetSeamMirrorLine(const QLineF &line)
{
d->m_seamMirrorLine = line;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetMappedSeamAllowanceMirrorLine() const -> QLineF
{
return d->m_matrix.map(d->m_seamAllowanceMirrorLine);
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetSeamAllowanceMirrorLine() const -> QLineF
{
return d->m_seamAllowanceMirrorLine;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetSeamAllowanceMirrorLine(const QLineF &line)
{
d->m_seamAllowanceMirrorLine = line;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFoldLineHeight() const -> qreal
{
return d->m_foldLineHeight;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetFoldLineHeight(qreal height)
{
d->m_foldLineHeight = height;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFoldLineWidth() const -> qreal
{
return d->m_foldLineWidth;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetFoldLineWidth(qreal width)
{
d->m_foldLineWidth = width;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFoldLineCenterPosition() const -> qreal
{
return d->m_foldLineCenter;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetFoldLineCenterPosition(qreal center)
{
d->m_foldLineCenter = center;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFoldLineOutlineFont() const -> QFont
{
return d->m_foldLineOutlineFont;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetFoldLineOutlineFont(const QFont &font)
{
d->m_foldLineOutlineFont = font;
}
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetFoldLineSVGFontFamily() const -> QString
{
return d->m_foldLineSvgFontFamily;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetFoldLineSVGFontFamily(const QString &font)
{
d->m_foldLineSvgFontFamily = font;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::SetGrainline(const VPieceGrainline &grainline) void VLayoutPiece::SetGrainline(const VPieceGrainline &grainline)
{ {
@ -1153,6 +1352,30 @@ auto VLayoutPiece::Diagonal() const -> qreal
return qSqrt(pow(rec.height(), 2) + pow(rec.width(), 2)); return qSqrt(pow(rec.height(), 2) + pow(rec.width(), 2));
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::FoldLine() const -> VFoldLine
{
QLineF const foldLine = IsHideMainPath() ? GetSeamAllowanceMirrorLine() : GetSeamMirrorLine();
VFoldLine fLine(foldLine, GetFoldLineType());
fLine.SetLabelSvgFontSize(GetFoldLineSvgFontSize());
fLine.SetLabelFontItalic(IsFoldLineLabelFontItalic());
fLine.SetLabelFontBold(IsFoldLineLabelFontBold());
fLine.SetLabel(GetFoldLineLabel());
fLine.SetLabelAlignment(GetFoldLineLabelAlignment());
fLine.SetHeight(GetFoldLineHeight());
fLine.SetWidth(GetFoldLineWidth());
fLine.SetCenterPosition(GetFoldLineCenterPosition());
fLine.SetMatrix(GetMatrix());
fLine.SetHorizontallyFlipped(IsHorizontallyFlipped());
fLine.SetVerticallyFlipped(IsVerticallyFlipped());
fLine.SetXScale(GetXScale());
fLine.SetYScale(GetYScale());
fLine.SetOutlineFont(GetFoldLineOutlineFont());
fLine.SetSvgFont(GetFoldLineSVGFontFamily());
return fLine;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::isNull() const -> bool auto VLayoutPiece::isNull() const -> bool
{ {
@ -1177,8 +1400,8 @@ void VLayoutPiece::SetLayoutAllowancePoints(bool togetherWithNotches)
if (d->m_layoutWidth > 0) if (d->m_layoutWidth > 0)
{ {
QVector<VLayoutPoint> pieceBoundary = IsSeamAllowance() && not IsSeamAllowanceBuiltIn() QVector<VLayoutPoint> pieceBoundary = IsSeamAllowance() && not IsSeamAllowanceBuiltIn()
? GetMappedSeamAllowancePoints() ? GetMappedFullSeamAllowancePoints()
: GetMappedContourPoints(); : GetMappedFullContourPoints();
if (togetherWithNotches) if (togetherWithNotches)
{ {
@ -1188,6 +1411,10 @@ void VLayoutPiece::SetLayoutAllowancePoints(bool togetherWithNotches)
VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance); VBoundary boundary(pieceBoundary, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(GetName()); boundary.SetPieceName(GetName());
if (IsShowFullPiece())
{
boundary.SetMirrorLine(GetMappedSeamAllowanceMirrorLine());
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, true); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, true);
pieceBoundary.clear(); pieceBoundary.clear();
@ -1220,14 +1447,14 @@ void VLayoutPiece::SetLayoutAllowancePoints(bool togetherWithNotches)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetMappedExternalContourPoints() const -> QVector<VLayoutPoint> auto VLayoutPiece::GetMappedExternalContourPoints() const -> QVector<VLayoutPoint>
{ {
return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetMappedSeamAllowancePoints() return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetMappedFullSeamAllowancePoints()
: GetMappedContourPoints(); : GetMappedFullContourPoints();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::GetExternalContourPoints() const -> QVector<VLayoutPoint> auto VLayoutPiece::GetExternalContourPoints() const -> QVector<VLayoutPoint>
{ {
return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetSeamAllowancePoints() : GetContourPoints(); return IsSeamAllowance() && not IsSeamAllowanceBuiltIn() ? GetFullSeamAllowancePoints() : GetFullContourPoints();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -1264,16 +1491,18 @@ void VLayoutPiece::SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels)
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::MappedInternalPathsForCut(bool cut) const -> QVector<QVector<VLayoutPoint>> auto VLayoutPiece::MappedInternalPathsForCut(bool cut) const -> QVector<VLayoutPiecePath>
{ {
QVector<QVector<VLayoutPoint>> paths; QVector<VLayoutPiecePath> paths;
paths.reserve(d->m_internalPaths.size()); paths.reserve(d->m_internalPaths.size());
for (const auto &path : d->m_internalPaths) for (const auto &path : d->m_internalPaths)
{ {
if (path.IsCutPath() == cut) if (path.IsCutPath() == cut)
{ {
paths.append(Map(path.Points())); VLayoutPiecePath iPath = path;
iPath.SetPoints(Map(path.Points()));
paths.append(iPath);
} }
} }
@ -1311,8 +1540,12 @@ auto VLayoutPiece::ContourPath(bool togetherWithNotches, bool showLayoutAllowanc
bool seamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn(); bool seamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn();
bool builtInSeamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn(); bool builtInSeamAllowance = IsSeamAllowance() && IsSeamAllowanceBuiltIn();
VBoundary boundary(d->m_contour, seamAllowance, builtInSeamAllowance); VBoundary boundary(GetFullContourPoints(), seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(GetName()); boundary.SetPieceName(GetName());
if (IsShowFullPiece())
{
boundary.SetMirrorLine(d->m_seamMirrorLine);
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(d->m_passmarks, true, false); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(d->m_passmarks, true, false);
for (const auto &item : sequence) for (const auto &item : sequence)
@ -1325,7 +1558,7 @@ auto VLayoutPiece::ContourPath(bool togetherWithNotches, bool showLayoutAllowanc
} }
else else
{ {
path = VGObject::PainterPath(GetContourPoints()); path = VGObject::PainterPath(GetFullContourPoints());
} }
} }
@ -1337,8 +1570,12 @@ auto VLayoutPiece::ContourPath(bool togetherWithNotches, bool showLayoutAllowanc
// Draw seam allowance // Draw seam allowance
if (togetherWithNotches) if (togetherWithNotches)
{ {
VBoundary boundary(d->m_seamAllowance, true); VBoundary boundary(GetFullSeamAllowancePoints(), true);
boundary.SetPieceName(GetName()); boundary.SetPieceName(GetName());
if (IsShowFullPiece())
{
boundary.SetMirrorLine(d->m_seamAllowanceMirrorLine);
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(d->m_passmarks, true, false); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(d->m_passmarks, true, false);
for (const auto &item : sequence) for (const auto &item : sequence)
@ -1351,7 +1588,7 @@ auto VLayoutPiece::ContourPath(bool togetherWithNotches, bool showLayoutAllowanc
} }
else else
{ {
QVector<VLayoutPoint> points = d->m_seamAllowance; QVector<VLayoutPoint> points = GetFullSeamAllowancePoints();
if (points.constLast().toPoint() != points.constFirst().toPoint()) if (points.constLast().toPoint() != points.constFirst().toPoint())
{ {
points.append(points.at(0)); // Should be always closed points.append(points.at(0)); // Should be always closed
@ -1364,16 +1601,32 @@ auto VLayoutPiece::ContourPath(bool togetherWithNotches, bool showLayoutAllowanc
if (!togetherWithNotches) if (!togetherWithNotches)
{ {
// Draw passmarks // Draw passmarks
QPainterPath passmaksPath;
for (const auto &passmark : d->m_passmarks) for (const auto &passmark : d->m_passmarks)
{ {
QPainterPath passmaksPath;
for (const auto &line : passmark.lines) for (const auto &line : passmark.lines)
{ {
passmaksPath.moveTo(line.p1()); passmaksPath.moveTo(line.p1());
passmaksPath.lineTo(line.p2()); passmaksPath.lineTo(line.p2());
} }
path.addPath(passmaksPath);
if (!d->m_seamAllowanceMirrorLine.isNull() && IsShowFullPiece())
{
if (!VGObject::IsPointOnLineviaPDP(passmark.baseLine.p1(), d->m_seamAllowanceMirrorLine.p1(),
d->m_seamAllowanceMirrorLine.p2()))
{
QPainterPath mirroredPassmaksPath;
for (const auto &line : passmark.lines)
{
mirroredPassmaksPath.moveTo(line.p1());
mirroredPassmaksPath.lineTo(line.p2());
}
const QTransform matrix = VGObject::FlippingMatrix(d->m_seamAllowanceMirrorLine);
path.addPath(matrix.map(mirroredPassmaksPath));
}
}
} }
path.addPath(passmaksPath);
} }
path.setFillRule(Qt::WindingFill); path.setFillRule(Qt::WindingFill);
@ -1428,7 +1681,21 @@ auto VLayoutPiece::GetItem(bool textAsPaths, bool togetherWithNotches, bool show
for (const auto &path : d->m_internalPaths) for (const auto &path : d->m_internalPaths)
{ {
auto *pathItem = new QGraphicsPathItem(item); auto *pathItem = new QGraphicsPathItem(item);
pathItem->setPath(d->m_matrix.map(path.GetPainterPath()));
QPainterPath p = d->m_matrix.map(path.GetPainterPath());
if (!path.IsNotMirrored() && IsShowFullPiece() && !d->m_seamMirrorLine.isNull())
{
QVector<VLayoutPoint> points = path.Points();
const QTransform matrix = VGObject::FlippingMatrix(d->m_seamMirrorLine);
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const VLayoutPoint &point) { return VAbstractPiece::MapPoint(point, matrix); });
QVector<QPointF> casted;
CastTo(points, casted);
p.addPath(d->m_matrix.map(VPiecePath::MakePainterPath(casted)));
}
pathItem->setPath(p);
QPen pen = pathItem->pen(); QPen pen = pathItem->pen();
pen.setStyle(path.PenStyle()); pen.setStyle(path.PenStyle());
@ -1442,12 +1709,68 @@ auto VLayoutPiece::GetItem(bool textAsPaths, bool togetherWithNotches, bool show
QPen pen = pathItem->pen(); QPen pen = pathItem->pen();
pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine()); pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine());
pathItem->setPen(pen); pathItem->setPen(pen);
pathItem->setPath(d->m_matrix.map(LabelShapePath(PlaceLabelShape(label))));
QPainterPath path;
path.addPath(d->m_matrix.map(LabelShapePath(label)));
if (!label.IsNotMirrored() && IsShowFullPiece() && !d->m_seamMirrorLine.isNull())
{
PlaceLabelImg shape = VAbstractPiece::PlaceLabelShape(label);
const QTransform matrix = VGObject::FlippingMatrix(d->m_seamMirrorLine);
for (auto &points : shape)
{
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const VLayoutPoint &point) { return MapPoint(point, matrix); });
}
path.addPath(d->m_matrix.map(LabelShapePath(shape)));
}
pathItem->setPath(path);
} }
CreateLabelStrings(item, d->m_detailLabel, d->m_tmDetail, textAsPaths); CreateLabelStrings(item, d->m_detailLabel, d->m_tmDetail, textAsPaths);
CreateLabelStrings(item, d->m_patternInfo, d->m_tmPattern, textAsPaths); CreateLabelStrings(item, d->m_patternInfo, d->m_tmPattern, textAsPaths);
CreateGrainlineItem(item); CreateGrainlineItem(item);
CreateFoldLineItem(item, textAsPaths);
if (IsShowFullPiece())
{
bool mirrorFlag = false;
QPainterPath mirrorLinePath;
if (not IsSeamAllowance() || IsSeamAllowanceBuiltIn())
{
if (!d->m_seamMirrorLine.isNull())
{
QPainterPath mirrorPath;
mirrorPath.moveTo(d->m_matrix.map(d->m_seamMirrorLine.p1()));
mirrorPath.lineTo(d->m_matrix.map(d->m_seamMirrorLine.p2()));
mirrorLinePath.addPath(mirrorPath);
mirrorFlag = true;
}
}
else if (not IsSeamAllowanceBuiltIn())
{
if (!d->m_seamAllowanceMirrorLine.isNull())
{
QPainterPath mirrorPath;
mirrorPath.moveTo(d->m_matrix.map(d->m_seamAllowanceMirrorLine.p1()));
mirrorPath.lineTo(d->m_matrix.map(d->m_seamAllowanceMirrorLine.p2()));
mirrorLinePath.addPath(mirrorPath);
mirrorFlag = true;
}
}
if (mirrorFlag)
{
auto *mirrorLineItem = new QGraphicsPathItem(item);
QPen pen = mirrorLineItem->pen();
pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine());
pen.setStyle(Qt::DashDotLine);
mirrorLineItem->setPen(pen);
mirrorLineItem->setPath(mirrorLinePath);
}
}
return item; return item;
} }
@ -1456,7 +1779,7 @@ auto VLayoutPiece::GetItem(bool textAsPaths, bool togetherWithNotches, bool show
auto VLayoutPiece::IsLayoutAllowanceValid(bool togetherWithNotches) const -> bool auto VLayoutPiece::IsLayoutAllowanceValid(bool togetherWithNotches) const -> bool
{ {
QVector<VLayoutPoint> base = QVector<VLayoutPoint> base =
(IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->m_seamAllowance : d->m_contour; (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? GetFullSeamAllowancePoints() : GetFullContourPoints();
if (togetherWithNotches) if (togetherWithNotches)
{ {
@ -1466,6 +1789,10 @@ auto VLayoutPiece::IsLayoutAllowanceValid(bool togetherWithNotches) const -> boo
VBoundary boundary(base, seamAllowance, builtInSeamAllowance); VBoundary boundary(base, seamAllowance, builtInSeamAllowance);
boundary.SetPieceName(GetName()); boundary.SetPieceName(GetName());
if (IsShowFullPiece())
{
boundary.SetMirrorLine(d->m_seamAllowanceMirrorLine);
}
const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, true); const QList<VBoundarySequenceItemData> sequence = boundary.Combine(passmarks, false, true);
base.clear(); base.clear();
@ -1516,6 +1843,14 @@ auto VLayoutPiece::MapPlaceLabelShape(PlaceLabelImg shape) const -> PlaceLabelIm
return shape; return shape;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::MapPassmark(VLayoutPassmark passmark, const QTransform &matrix, bool mirror) -> VLayoutPassmark
{
passmark.lines = MapVector(passmark.lines, matrix, mirror);
passmark.baseLine = matrix.map(passmark.baseLine);
return passmark;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::BoundingRect(QVector<QPointF> points) -> QRectF auto VLayoutPiece::BoundingRect(QVector<QPointF> points) -> QRectF
{ {
@ -1589,7 +1924,6 @@ void VLayoutPiece::LabelStringsSVGFont(QGraphicsItem *parent, const QVector<QPoi
break; break;
} }
QString qsText = tl.m_qsText;
qreal dX = 0; qreal dX = 0;
if (tl.m_eAlign == 0 || (tl.m_eAlign & Qt::AlignLeft) > 0) if (tl.m_eAlign == 0 || (tl.m_eAlign & Qt::AlignLeft) > 0)
{ {
@ -1597,11 +1931,11 @@ void VLayoutPiece::LabelStringsSVGFont(QGraphicsItem *parent, const QVector<QPoi
} }
else if ((tl.m_eAlign & Qt::AlignHCenter) > 0) else if ((tl.m_eAlign & Qt::AlignHCenter) > 0)
{ {
dX = (dW - engine.TextWidth(qsText, penWidth)) / 2; dX = (dW - engine.TextWidth(tl.m_qsText, penWidth)) / 2;
} }
else if ((tl.m_eAlign & Qt::AlignRight) > 0) else if ((tl.m_eAlign & Qt::AlignRight) > 0)
{ {
dX = dW - engine.TextWidth(qsText, penWidth); dX = dW - engine.TextWidth(tl.m_qsText, penWidth);
} }
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
@ -1630,11 +1964,11 @@ void VLayoutPiece::LabelStringsSVGFont(QGraphicsItem *parent, const QVector<QPoi
pen.setWidthF(penWidth); pen.setWidthF(penWidth);
item->setPen(pen); item->setPen(pen);
item->setPath(engine.DrawPath(QPointF(), qsText)); item->setPath(engine.DrawPath(QPointF(), tl.m_qsText));
item->setBrush(QBrush(Qt::NoBrush)); item->setBrush(QBrush(Qt::NoBrush));
item->setTransform(labelMatrix); item->setTransform(labelMatrix);
dY += engine.FontHeight() + penWidth + tm.GetSpacing(); dY += engine.FontHeight() - penWidth * 2 + tm.GetSpacing();
} }
} }
@ -1686,7 +2020,6 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector<
break; break;
} }
QString qsText = tl.m_qsText;
qreal dX = 0; qreal dX = 0;
if (tl.m_eAlign == 0 || (tl.m_eAlign & Qt::AlignLeft) > 0) if (tl.m_eAlign == 0 || (tl.m_eAlign & Qt::AlignLeft) > 0)
{ {
@ -1694,11 +2027,11 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector<
} }
else if ((tl.m_eAlign & Qt::AlignHCenter) > 0) else if ((tl.m_eAlign & Qt::AlignHCenter) > 0)
{ {
dX = (dW - TextWidth(fm, qsText)) / 2; dX = (dW - TextWidth(fm, tl.m_qsText)) / 2;
} }
else if ((tl.m_eAlign & Qt::AlignRight) > 0) else if ((tl.m_eAlign & Qt::AlignRight) > 0)
{ {
dX = dW - TextWidth(fm, qsText); dX = dW - TextWidth(fm, tl.m_qsText);
} }
// set up the rotation around top-left corner matrix // set up the rotation around top-left corner matrix
@ -1708,15 +2041,14 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector<
{ {
labelMatrix.scale(-1, 1); labelMatrix.scale(-1, 1);
labelMatrix.rotate(-angle); labelMatrix.rotate(-angle);
labelMatrix.translate(-dW, 0); labelMatrix.translate(-tm.MaxLineWidthOutlineFont(static_cast<int>(dW)), 0);
labelMatrix.translate(dX, dY); // Each string has own position
} }
else else
{ {
labelMatrix.rotate(angle); labelMatrix.rotate(angle);
labelMatrix.translate(dX, dY); // Each string has own position
} }
labelMatrix.translate(dX, dY); // Each string has own position
labelMatrix *= d->m_matrix; labelMatrix *= d->m_matrix;
if (textAsPaths) if (textAsPaths)
@ -1726,7 +2058,7 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector<
if (settings->GetSingleStrokeOutlineFont()) if (settings->GetSingleStrokeOutlineFont())
{ {
int w = 0; int w = 0;
for (auto c : qAsConst(qsText)) for (auto c : qAsConst(tl.m_qsText))
{ {
path.addPath(corrector.DrawChar(w, static_cast<qreal>(fm.ascent()), c)); path.addPath(corrector.DrawChar(w, static_cast<qreal>(fm.ascent()), c));
w += TextWidth(fm, c); w += TextWidth(fm, c);
@ -1734,7 +2066,7 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector<
} }
else else
{ {
path.addText(0, static_cast<qreal>(fm.ascent()), fnt, qsText); path.addText(0, static_cast<qreal>(fm.ascent()), fnt, tl.m_qsText);
} }
auto *item = new QGraphicsPathItem(parent); auto *item = new QGraphicsPathItem(parent);
@ -1749,16 +2081,16 @@ void VLayoutPiece::LabelStringsOutlineFont(QGraphicsItem *parent, const QVector<
item->setBrush(settings->GetSingleStrokeOutlineFont() ? QBrush(Qt::NoBrush) : QBrush(Qt::black)); item->setBrush(settings->GetSingleStrokeOutlineFont() ? QBrush(Qt::NoBrush) : QBrush(Qt::black));
item->setTransform(labelMatrix); item->setTransform(labelMatrix);
dY += fm.height() + penWidth + tm.GetSpacing(); dY += fm.height() + penWidth * 2 + MmToPixel(1.5) + tm.GetSpacing();
} }
else else
{ {
auto *item = new QGraphicsSimpleTextItem(parent); auto *item = new QGraphicsSimpleTextItem(parent);
item->setFont(fnt); item->setFont(fnt);
item->setText(qsText); item->setText(tl.m_qsText);
item->setTransform(labelMatrix); item->setTransform(labelMatrix);
dY += (fm.height() + tm.GetSpacing()); dY += (fm.height() + MmToPixel(1.5) + tm.GetSpacing());
} }
} }
} }
@ -1797,6 +2129,83 @@ void VLayoutPiece::CreateGrainlineItem(QGraphicsItem *parent) const
item->setPen(pen); item->setPen(pen);
} }
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiece::CreateFoldLineItem(QGraphicsItem *parent, bool textAsPaths) const
{
SCASSERT(parent != nullptr)
if (GetFoldLineType() == FoldLineType::None)
{
return;
}
VFoldLine const fLine = FoldLine();
QVector<QPainterPath> const shape = fLine.FoldLinePath();
if (shape.isEmpty())
{
return;
}
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
if (!textAsPaths && !settings->GetSingleStrokeOutlineFont() && !settings->GetSingleLineFonts())
{
auto *item = new QGraphicsSimpleTextItem(parent);
fLine.UpdateFoldLineLabel(item);
}
auto FoldLineMark = [parent](const QPainterPath &shape)
{
auto *item = new VGraphicsFoldLineItem(shape, parent);
item->SetCustomPen(true);
QPen pen = item->pen();
pen.setWidthF(VAbstractApplication::VApp()->Settings()->WidthHairLine());
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
item->setPen(pen);
};
auto FoldLineLabel = [parent](const QPainterPath &shape)
{
auto *item = new QGraphicsPathItem(parent);
item->setPath(shape);
VCommonSettings *settings = VAbstractApplication::VApp()->Settings();
QPen itemPen = item->pen();
itemPen.setColor(Qt::black);
itemPen.setCapStyle(Qt::RoundCap);
itemPen.setJoinStyle(Qt::RoundJoin);
itemPen.setWidthF(settings->WidthHairLine());
item->setPen(itemPen);
item->setBrush(settings->GetSingleStrokeOutlineFont() || settings->GetSingleLineFonts() ? QBrush(Qt::NoBrush)
: QBrush(Qt::black));
};
if (GetFoldLineType() == FoldLineType::ThreeDots || GetFoldLineType() == FoldLineType::ThreeX ||
GetFoldLineType() == FoldLineType::TwoArrows)
{
FoldLineMark(shape.constFirst());
}
else if (GetFoldLineType() == FoldLineType::Text)
{
if (settings->GetSingleStrokeOutlineFont() || settings->GetSingleLineFonts())
{
FoldLineLabel(shape.constFirst());
}
}
else
{
FoldLineMark(shape.constFirst());
if (shape.size() > 1 && (settings->GetSingleStrokeOutlineFont() || settings->GetSingleLineFonts()))
{
FoldLineLabel(shape.constLast());
}
}
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiece::DetailPath() const -> QVector<VLayoutPoint> auto VLayoutPiece::DetailPath() const -> QVector<VLayoutPoint>
{ {
@ -1830,7 +2239,7 @@ auto VLayoutPiece::GetMainPathItem() const -> QGraphicsPathItem *
QPainterPath path; QPainterPath path;
// contour // contour
QVector<VLayoutPoint> points = GetMappedContourPoints(); QVector<VLayoutPoint> const points = GetMappedContourPoints();
path.moveTo(points.at(0)); path.moveTo(points.at(0));
for (qint32 i = 1; i < points.count(); ++i) for (qint32 i = 1; i < points.count(); ++i)

View File

@ -63,16 +63,7 @@ class VPieceLabelData;
class VAbstractPattern; class VAbstractPattern;
class VPatternLabelData; class VPatternLabelData;
class VLayoutPoint; class VLayoutPoint;
class VFoldLine;
template <typename T> struct IsLayoutPoint
{
static const bool value = false;
};
template <> struct IsLayoutPoint<VLayoutPoint>
{
static const bool value = true;
};
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wsuggest-final-types") QT_WARNING_DISABLE_GCC("-Wsuggest-final-types")
@ -100,10 +91,14 @@ public:
auto GetUniqueID() const -> QString override; auto GetUniqueID() const -> QString override;
auto GetMappedContourPoints() const -> QVector<VLayoutPoint>; auto GetMappedContourPoints() const -> QVector<VLayoutPoint>;
auto GetMappedFullContourPoints() const -> QVector<VLayoutPoint>;
auto GetFullContourPoints() const -> QVector<VLayoutPoint>;
auto GetContourPoints() const -> QVector<VLayoutPoint>; auto GetContourPoints() const -> QVector<VLayoutPoint>;
void SetContourPoints(const QVector<VLayoutPoint> &points, bool hideMainPath = false); void SetContourPoints(const QVector<VLayoutPoint> &points, bool hideMainPath = false);
auto GetMappedSeamAllowancePoints() const -> QVector<VLayoutPoint>; auto GetMappedSeamAllowancePoints() const -> QVector<VLayoutPoint>;
auto GetMappedFullSeamAllowancePoints() const -> QVector<VLayoutPoint>;
auto GetFullSeamAllowancePoints() const -> QVector<VLayoutPoint>;
auto GetSeamAllowancePoints() const -> QVector<VLayoutPoint>; auto GetSeamAllowancePoints() const -> QVector<VLayoutPoint>;
void SetSeamAllowancePoints(const QVector<VLayoutPoint> &points, bool seamAllowance = true, void SetSeamAllowancePoints(const QVector<VLayoutPoint> &points, bool seamAllowance = true,
bool seamAllowanceBuiltIn = false); bool seamAllowanceBuiltIn = false);
@ -122,16 +117,14 @@ public:
auto GetPlaceLabels() const -> QVector<VLayoutPlaceLabel>; auto GetPlaceLabels() const -> QVector<VLayoutPlaceLabel>;
void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels); void SetPlaceLabels(const QVector<VLayoutPlaceLabel> &labels);
auto MappedInternalPathsForCut(bool cut) const -> QVector<QVector<VLayoutPoint>>; auto MappedInternalPathsForCut(bool cut) const -> QVector<VLayoutPiecePath>;
auto GetInternalPaths() const -> QVector<VLayoutPiecePath>; auto GetInternalPaths() const -> QVector<VLayoutPiecePath>;
void SetInternalPaths(const QVector<VLayoutPiecePath> &internalPaths); void SetInternalPaths(const QVector<VLayoutPiecePath> &internalPaths);
auto GetPieceTextPosition() const -> QPointF;
auto GetPieceText() const -> QStringList; auto GetPieceText() const -> QStringList;
void SetPieceText(const QString &qsName, const VPieceLabelData &data, const QFont &font, void SetPieceText(const QString &qsName, const VPieceLabelData &data, const QFont &font,
const QString &SVGFontFamily, const VContainer *pattern); const QString &SVGFontFamily, const VContainer *pattern);
auto GetPatternTextPosition() const -> QPointF;
auto GetPatternText() const -> QStringList; auto GetPatternText() const -> QStringList;
void SetPatternInfo(VAbstractPattern *pDoc, const VPatternLabelData &geom, const QFont &font, void SetPatternInfo(VAbstractPattern *pDoc, const VPatternLabelData &geom, const QFont &font,
const QString &SVGFontFamily, const VContainer *pattern); const QString &SVGFontFamily, const VContainer *pattern);
@ -183,6 +176,29 @@ public:
auto GetPatternLabelData() const -> VTextManager; auto GetPatternLabelData() const -> VTextManager;
void SetPatternLabelData(const VTextManager &data); void SetPatternLabelData(const VTextManager &data);
auto GetMappedSeamMirrorLine() const -> QLineF;
auto GetSeamMirrorLine() const -> QLineF;
void SetSeamMirrorLine(const QLineF &line);
auto GetMappedSeamAllowanceMirrorLine() const -> QLineF;
auto GetSeamAllowanceMirrorLine() const -> QLineF;
void SetSeamAllowanceMirrorLine(const QLineF &line);
auto GetFoldLineHeight() const -> qreal;
void SetFoldLineHeight(qreal height);
auto GetFoldLineWidth() const -> qreal;
void SetFoldLineWidth(qreal width);
auto GetFoldLineCenterPosition() const -> qreal;
void SetFoldLineCenterPosition(qreal center);
auto GetFoldLineOutlineFont() const -> QFont;
void SetFoldLineOutlineFont(const QFont &font);
auto GetFoldLineSVGFontFamily() const -> QString;
void SetFoldLineSVGFontFamily(const QString &font);
void Translate(const QPointF &p); void Translate(const QPointF &p);
void Translate(qreal dx, qreal dy); void Translate(qreal dx, qreal dy);
void Scale(qreal sx, qreal sy); void Scale(qreal sx, qreal sy);
@ -201,6 +217,8 @@ public:
auto MappedLayoutBoundingRect() const -> QRectF; auto MappedLayoutBoundingRect() const -> QRectF;
auto Diagonal() const -> qreal; auto Diagonal() const -> qreal;
auto FoldLine() const -> VFoldLine;
static auto BoundingRect(QVector<QPointF> points) -> QRectF; static auto BoundingRect(QVector<QPointF> points) -> QRectF;
static auto GrainlinePath(const GrainlineShape &shape) -> QPainterPath; static auto GrainlinePath(const GrainlineShape &shape) -> QPainterPath;
@ -226,14 +244,7 @@ public:
auto MapPlaceLabelShape(PlaceLabelImg shape) const -> PlaceLabelImg; auto MapPlaceLabelShape(PlaceLabelImg shape) const -> PlaceLabelImg;
template <class T> static auto MapPassmark(VLayoutPassmark passmark, const QTransform &matrix, bool mirror) -> VLayoutPassmark;
static auto MapVector(QVector<T> points, const QTransform &matrix, bool mirror = false) -> QVector<T>;
template <class T>
static auto MapPoint(T obj, const QTransform &matrix) -> typename std::enable_if<!IsLayoutPoint<T>::value, T>::type;
template <class T>
static auto MapPoint(T obj, const QTransform &matrix) -> typename std::enable_if<IsLayoutPoint<T>::value, T>::type;
protected: protected:
void SetGrainline(const VPieceGrainline &grainline); void SetGrainline(const VPieceGrainline &grainline);
@ -254,6 +265,7 @@ private:
void CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape, const VTextManager &tm, void CreateLabelStrings(QGraphicsItem *parent, const QVector<QPointF> &labelShape, const VTextManager &tm,
bool textAsPaths) const; bool textAsPaths) const;
void CreateGrainlineItem(QGraphicsItem *parent) const; void CreateGrainlineItem(QGraphicsItem *parent) const;
void CreateFoldLineItem(QGraphicsItem *parent, bool textAsPaths) const;
template <class T> auto Map(QVector<T> points) const -> QVector<T>; template <class T> auto Map(QVector<T> points) const -> QVector<T>;
auto Map(const GrainlineShape &shape) const -> GrainlineShape; auto Map(const GrainlineShape &shape) const -> GrainlineShape;
@ -266,36 +278,4 @@ QT_WARNING_POP
Q_DECLARE_TYPEINFO(VLayoutPiece, Q_MOVABLE_TYPE); // NOLINT Q_DECLARE_TYPEINFO(VLayoutPiece, Q_MOVABLE_TYPE); // NOLINT
//---------------------------------------------------------------------------------------------------------------------
template <class T>
inline auto VLayoutPiece::MapVector(QVector<T> points, const QTransform &matrix, bool mirror) -> QVector<T>
{
std::transform(points.begin(), points.end(), points.begin(),
[matrix](const T &point) { return MapPoint(point, matrix); });
if (mirror)
{
std::reverse(points.begin(), points.end());
}
return points;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T>
auto VLayoutPiece::MapPoint(T obj, const QTransform &matrix) ->
typename std::enable_if<!IsLayoutPoint<T>::value, T>::type
{
return matrix.map(obj);
}
//---------------------------------------------------------------------------------------------------------------------
template <typename T>
auto VLayoutPiece::MapPoint(T obj, const QTransform &matrix) ->
typename std::enable_if<IsLayoutPoint<T>::value, T>::type
{
auto p = matrix.map(obj);
obj.setX(p.x());
obj.setY(p.y());
return obj;
}
#endif // VLAYOUTDETAIL_H #endif // VLAYOUTDETAIL_H

View File

@ -115,11 +115,21 @@ public:
qreal m_xScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal m_xScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_yScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes) qreal m_yScale{1.0}; // NOLINT(misc-non-private-member-variables-in-classes)
QLineF m_seamMirrorLine{}; // NOLINT(misc-non-private-member-variables-in-classes)
QLineF m_seamAllowanceMirrorLine{}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_foldLineHeight{0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_foldLineWidth{0}; // NOLINT(misc-non-private-member-variables-in-classes)
qreal m_foldLineCenter{0.5}; // NOLINT(misc-non-private-member-variables-in-classes)
QFont m_foldLineOutlineFont{}; // NOLINT (misc-non-private-member-variables-in-classes)
QString m_foldLineSvgFontFamily{}; // NOLINT (misc-non-private-member-variables-in-classes)
private: private:
Q_DISABLE_ASSIGN_MOVE(VLayoutPieceData) // NOLINT Q_DISABLE_ASSIGN_MOVE(VLayoutPieceData) // NOLINT
static constexpr quint32 streamHeader{0x80D7D009}; // CRC-32Q string "VLayoutPieceData" static constexpr quint32 streamHeader{0x80D7D009}; // CRC-32Q string "VLayoutPieceData"
static constexpr quint16 classVersion{6}; static constexpr quint16 classVersion{7};
}; };
QT_WARNING_POP QT_WARNING_POP
@ -157,6 +167,13 @@ inline auto operator<<(QDataStream &dataStream, const VLayoutPieceData &piece) -
dataStream << piece.m_yScale; dataStream << piece.m_yScale;
dataStream << piece.m_grainline; dataStream << piece.m_grainline;
dataStream << piece.m_horizontallyFlipped; dataStream << piece.m_horizontallyFlipped;
dataStream << piece.m_seamMirrorLine;
dataStream << piece.m_seamAllowanceMirrorLine;
dataStream << piece.m_foldLineHeight;
dataStream << piece.m_foldLineWidth;
dataStream << piece.m_foldLineCenter;
dataStream << piece.m_foldLineOutlineFont;
dataStream << piece.m_foldLineSvgFontFamily;
return dataStream; return dataStream;
} }
@ -275,6 +292,17 @@ inline auto operator>>(QDataStream &dataStream, VLayoutPieceData &piece) -> QDat
dataStream >> piece.m_horizontallyFlipped; dataStream >> piece.m_horizontallyFlipped;
} }
if (actualClassVersion >= 7)
{
dataStream >> piece.m_seamMirrorLine;
dataStream >> piece.m_seamAllowanceMirrorLine;
dataStream >> piece.m_foldLineHeight;
dataStream >> piece.m_foldLineWidth;
dataStream >> piece.m_foldLineCenter;
dataStream >> piece.m_foldLineOutlineFont;
dataStream >> piece.m_foldLineSvgFontFamily;
}
return dataStream; return dataStream;
} }

View File

@ -139,3 +139,15 @@ void VLayoutPiecePath::SetCutPath(bool cut)
{ {
d->m_cut = cut; d->m_cut = cut;
} }
//---------------------------------------------------------------------------------------------------------------------
auto VLayoutPiecePath::IsNotMirrored() const -> bool
{
return d->m_notMirrored;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutPiecePath::SetNotMirrored(bool value)
{
d->m_notMirrored = value;
}

View File

@ -63,6 +63,9 @@ public:
auto IsCutPath() const -> bool; auto IsCutPath() const -> bool;
void SetCutPath(bool cut); void SetCutPath(bool cut);
auto IsNotMirrored() const -> bool;
void SetNotMirrored(bool value);
friend auto operator<<(QDataStream &dataStream, const VLayoutPiecePath &path) -> QDataStream &; friend auto operator<<(QDataStream &dataStream, const VLayoutPiecePath &path) -> QDataStream &;
friend auto operator>>(QDataStream &dataStream, VLayoutPiecePath &path) -> QDataStream &; friend auto operator>>(QDataStream &dataStream, VLayoutPiecePath &path) -> QDataStream &;

View File

@ -62,13 +62,14 @@ public:
/** @brief m_penStyle path pen style. */ /** @brief m_penStyle path pen style. */
Qt::PenStyle m_penStyle{Qt::SolidLine}; // NOLINT(misc-non-private-member-variables-in-classes) Qt::PenStyle m_penStyle{Qt::SolidLine}; // NOLINT(misc-non-private-member-variables-in-classes)
bool m_cut{false}; // NOLINT(misc-non-private-member-variables-in-classes) bool m_cut{false}; // NOLINT(misc-non-private-member-variables-in-classes)
bool m_notMirrored{false}; // NOLINT(misc-non-private-member-variables-in-classes)
private: private:
Q_DISABLE_ASSIGN_MOVE(VLayoutPiecePathData) // NOLINT Q_DISABLE_ASSIGN_MOVE(VLayoutPiecePathData) // NOLINT
static constexpr quint32 streamHeader = 0xA53F0225; // CRC-32Q string "VLayoutPiecePathData" static constexpr quint32 streamHeader = 0xA53F0225; // CRC-32Q string "VLayoutPiecePathData"
static constexpr quint16 classVersion = 2; static constexpr quint16 classVersion = 3;
}; };
QT_WARNING_POP QT_WARNING_POP
@ -87,7 +88,7 @@ inline VLayoutPiecePathData::VLayoutPiecePathData(const QVector<VLayoutPoint> &p
// Friend functions // Friend functions
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto operator<<(QDataStream &dataStream, const VLayoutPiecePathData &path) -> QDataStream & inline auto operator<<(QDataStream &dataStream, const VLayoutPiecePathData &path) -> QDataStream &
{ {
dataStream << VLayoutPiecePathData::streamHeader << VLayoutPiecePathData::classVersion; dataStream << VLayoutPiecePathData::streamHeader << VLayoutPiecePathData::classVersion;
@ -96,13 +97,14 @@ auto operator<<(QDataStream &dataStream, const VLayoutPiecePathData &path) -> QD
dataStream << path.m_penStyle; dataStream << path.m_penStyle;
dataStream << path.m_cut; dataStream << path.m_cut;
// Added in classVersion = 2 // Added in classVersion = 3
dataStream << path.m_notMirrored;
return dataStream; return dataStream;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
auto operator>>(QDataStream &dataStream, VLayoutPiecePathData &path) -> QDataStream & inline auto operator>>(QDataStream &dataStream, VLayoutPiecePathData &path) -> QDataStream &
{ {
quint32 actualStreamHeader = 0; quint32 actualStreamHeader = 0;
dataStream >> actualStreamHeader; dataStream >> actualStreamHeader;
@ -141,10 +143,10 @@ auto operator>>(QDataStream &dataStream, VLayoutPiecePathData &path) -> QDataStr
dataStream >> path.m_penStyle; dataStream >> path.m_penStyle;
dataStream >> path.m_cut; dataStream >> path.m_cut;
// if (actualClassVersion >= 2) if (actualClassVersion >= 3)
// { {
dataStream >> path.m_notMirrored;
// } }
return dataStream; return dataStream;
} }

View File

@ -68,7 +68,7 @@ QPainterPath ShowDirection(const QLineF &edge)
arrow.setLength(edge.length() / 2.0); arrow.setLength(edge.length() / 2.0);
// Reverse line because we want start arrow from this point // Reverse line because we want start arrow from this point
arrow = QLineF(arrow.p2(), arrow.p1()); Swap(arrow);
const qreal angle = arrow.angle(); // we each time change line angle, better save original angle value const qreal angle = arrow.angle(); // we each time change line angle, better save original angle value
arrow.setLength(arrowLength); // arrow length in pixels arrow.setLength(arrowLength); // arrow length in pixels

View File

@ -44,17 +44,17 @@
#include "../vmisc/svgfont/vsvgfontengine.h" #include "../vmisc/svgfont/vsvgfontengine.h"
#include "../vmisc/vabstractvalapplication.h" #include "../vmisc/vabstractvalapplication.h"
#include "../vmisc/vcommonsettings.h" #include "../vmisc/vcommonsettings.h"
#include "../vmisc/vtranslator.h"
#include "../vpatterndb/calculator.h"
#include "../vpatterndb/floatItemData/vpiecelabeldata.h" #include "../vpatterndb/floatItemData/vpiecelabeldata.h"
#include "../vpatterndb/variables/vmeasurement.h"
#include "../vpatterndb/vcontainer.h"
#include "vtextmanager.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 9, 0)
#include "../vmisc/vdatastreamenum.h" #include "../vmisc/vdatastreamenum.h"
#endif #endif
#include "../vpatterndb/calculator.h"
#include "../vpatterndb/variables/vmeasurement.h"
#include "../vpatterndb/vcontainer.h"
#include "vtextmanager.h"
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;
namespace namespace
@ -471,7 +471,7 @@ auto PreparePlaceholders(const VAbstractPattern *doc, const VContainer *data, bo
QMap<QString, QString> placeholders; QMap<QString, QString> placeholders;
// Pattern tags // Pattern tags
QLocale locale(VAbstractApplication::VApp()->Settings()->GetLocale()); QLocale const locale(VAbstractApplication::VApp()->Settings()->GetLocale());
const QString date = locale.toString(QDate::currentDate(), doc->GetLabelDateFormat()); const QString date = locale.toString(QDate::currentDate(), doc->GetLabelDateFormat());
placeholders.insert(pl_date, date); placeholders.insert(pl_date, date);
@ -516,7 +516,7 @@ auto PreparePlaceholders(const VAbstractPattern *doc, const VContainer *data, bo
placeholders.insert(pl_pQuantity, QString()); placeholders.insert(pl_pQuantity, QString());
placeholders.insert(pl_wOnFold, QString()); placeholders.insert(pl_wOnFold, QString());
QSharedPointer<QTranslator> phTr = VAbstractValApplication::VApp()->GetPlaceholderTranslator(); QSharedPointer<VTranslator> const phTr = VAbstractApplication::VApp()->GetPlaceholderTranslator();
placeholders.insert(pl_mFabric, phTr->translate("Placeholder", "Fabric")); placeholders.insert(pl_mFabric, phTr->translate("Placeholder", "Fabric"));
placeholders.insert(pl_mLining, phTr->translate("Placeholder", "Lining")); placeholders.insert(pl_mLining, phTr->translate("Placeholder", "Lining"));
@ -541,7 +541,7 @@ void InitPiecePlaceholders(QMap<QString, QString> &placeholders, const QString &
if (data.IsOnFold()) if (data.IsOnFold())
{ {
QSharedPointer<QTranslator> phTr = VAbstractValApplication::VApp()->GetPlaceholderTranslator(); QSharedPointer<VTranslator> phTr = VAbstractApplication::VApp()->GetPlaceholderTranslator();
placeholders[pl_wOnFold] = phTr->translate("Placeholder", "on fold"); placeholders[pl_wOnFold] = phTr->translate("Placeholder", "on fold");
} }
} }

View File

@ -418,10 +418,8 @@ auto PassmarkAngleTypeToString(PassmarkAngleType type) -> QString
case PassmarkAngleType::Intersection2OnlyRight: case PassmarkAngleType::Intersection2OnlyRight:
return strIntersection2OnlyRight; return strIntersection2OnlyRight;
default: default:
break; return strStraightforward;
} }
return strStraightforward;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -450,9 +448,62 @@ auto StringToPassmarkAngleType(const QString &value) -> PassmarkAngleType
case 7: case 7:
return PassmarkAngleType::Intersection2OnlyRight; return PassmarkAngleType::Intersection2OnlyRight;
default: default:
break; return PassmarkAngleType::Straightforward;
} }
return PassmarkAngleType::Straightforward; }
//---------------------------------------------------------------------------------------------------------------------
auto FoldLineTypeToString(FoldLineType type) -> QString
{
switch (type)
{
case FoldLineType::TwoArrowsTextUnder:
return strFoldTypeTwoArrowsTextUnder;
case FoldLineType::TwoArrows:
return strFoldTypeTwoArrows;
case FoldLineType::Text:
return strFoldTypeText;
case FoldLineType::ThreeDots:
return strFoldTypeThreeDots;
case FoldLineType::ThreeX:
return strFoldTypeThreeX;
case FoldLineType::None:
return strFoldTypeNone;
case FoldLineType::TwoArrowsTextAbove:
default:
return strFoldTypeTwoArrowsTextAbove;
}
}
//---------------------------------------------------------------------------------------------------------------------
auto StringToFoldLineType(const QString &value) -> FoldLineType
{
const QStringList values{strFoldTypeTwoArrowsTextAbove, // 0
strFoldTypeTwoArrowsTextUnder, // 1
strFoldTypeTwoArrows, // 2
strFoldTypeText, // 3
strFoldTypeThreeDots, // 4
strFoldTypeThreeX, // 5
strFoldTypeNone}; // 6
switch (values.indexOf(value))
{
case 1:
return FoldLineType::TwoArrowsTextUnder;
case 2:
return FoldLineType::TwoArrows;
case 3:
return FoldLineType::Text;
case 4:
return FoldLineType::ThreeDots;
case 5:
return FoldLineType::ThreeX;
case 6:
return FoldLineType::None;
case 0:
default:
return FoldLineType::TwoArrowsTextAbove;
};
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -211,6 +211,23 @@ enum class PiecePathIncludeType : quint8
AsCustomSA = 1 AsCustomSA = 1
}; };
constexpr unsigned int defFoldLineFontSize{12};
enum class FoldLineType : quint8
{
TwoArrowsTextAbove = 0, // Default
TwoArrowsTextUnder,
TwoArrows,
Text,
ThreeDots,
ThreeX,
None,
LAST_ONE_DO_NOT_USE
};
auto FoldLineTypeToString(FoldLineType type) -> QString;
auto StringToFoldLineType(const QString &value) -> FoldLineType;
enum class PiecePathType : quint8 enum class PiecePathType : quint8
{ {
PiecePath = 0, PiecePath = 0,
@ -348,6 +365,7 @@ enum class Vis : ToolVisHolderType
enum class Layout : ToolVisHolderType enum class Layout : ToolVisHolderType
{ {
GrainlineItem = static_cast<ToolVisHolderType>(Vis::LAST_ONE_DO_NOT_USE), GrainlineItem = static_cast<ToolVisHolderType>(Vis::LAST_ONE_DO_NOT_USE),
FoldLineItem,
LAST_ONE_DO_NOT_USE // add new stuffs above this, this constant must be last and never used LAST_ONE_DO_NOT_USE // add new stuffs above this, this constant must be last and never used
}; };

View File

@ -160,6 +160,13 @@ const QString strIntersection2OnlyRight = QStringLiteral("intersection2Right");
const QString strTypeIncrement = QStringLiteral("increment"); const QString strTypeIncrement = QStringLiteral("increment");
const QString strTypeSeparator = QStringLiteral("separator"); const QString strTypeSeparator = QStringLiteral("separator");
const QString strTypeMeasurement = QStringLiteral("measurement"); const QString strTypeMeasurement = QStringLiteral("measurement");
const QString strFoldTypeTwoArrowsTextAbove = QStringLiteral("2ArrowsTextAbove");
const QString strFoldTypeTwoArrowsTextUnder = QStringLiteral("2ArrowsTextUnder");
const QString strFoldTypeTwoArrows = QStringLiteral("2Arrows");
const QString strFoldTypeText = QStringLiteral("text");
const QString strFoldTypeThreeDots = QStringLiteral("3dots");
const QString strFoldTypeThreeX = QStringLiteral("3X");
const QString strFoldTypeNone = QStringLiteral("none");
const QString unitMM = QStringLiteral("mm"); const QString unitMM = QStringLiteral("mm");
const QString unitCM = QStringLiteral("cm"); const QString unitCM = QStringLiteral("cm");

View File

@ -164,6 +164,13 @@ extern const QString strIntersection2OnlyRight;
extern const QString strTypeIncrement; extern const QString strTypeIncrement;
extern const QString strTypeSeparator; extern const QString strTypeSeparator;
extern const QString strTypeMeasurement; extern const QString strTypeMeasurement;
extern const QString strFoldTypeTwoArrowsTextAbove;
extern const QString strFoldTypeTwoArrowsTextUnder;
extern const QString strFoldTypeTwoArrows;
extern const QString strFoldTypeText;
extern const QString strFoldTypeThreeDots;
extern const QString strFoldTypeThreeX;
extern const QString strFoldTypeNone;
extern const QString unitMM; extern const QString unitMM;
extern const QString unitCM; extern const QString unitCM;

View File

@ -213,5 +213,7 @@
<file>icon/light/16x16/viewimage.png</file> <file>icon/light/16x16/viewimage.png</file>
<file>icon/dark/16x16/viewimage.png</file> <file>icon/dark/16x16/viewimage.png</file>
<file>icon/dark/16x16/viewimage@2x.png</file> <file>icon/dark/16x16/viewimage@2x.png</file>
<file>icon/32x32/fold.png</file>
<file>icon/32x32/fold@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 827 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -31,6 +31,7 @@
}, },
"ManualLayoutStyle": { "ManualLayoutStyle": {
"SheetBorderColor": "#808080", "SheetBorderColor": "#808080",
"SheetFoldShadowColor": "#6699cc",
"SheetMarginColor": "#00b3ff", "SheetMarginColor": "#00b3ff",
"SheetGridColor": "#cccccc", "SheetGridColor": "#cccccc",
"SheetTileGridColor": "#80ff0000", "SheetTileGridColor": "#80ff0000",
@ -40,6 +41,7 @@
"PieceHoverColor": "#80c7f4f9", "PieceHoverColor": "#80c7f4f9",
"PieceHandleColor": "#add8e6", "PieceHandleColor": "#add8e6",
"PieceHandleHoverColor": "#90ee90", "PieceHandleHoverColor": "#90ee90",
"PieceSelectionBrushColor": [255, 160, 160, 60],
"CarrouselPieceColor": "#78a0c8", "CarrouselPieceColor": "#78a0c8",
"CarrouselPieceSelectedColor": "#80ffa0a0", "CarrouselPieceSelectedColor": "#80ffa0a0",
"CarrouselPieceBackgroundColor": "#202020", "CarrouselPieceBackgroundColor": "#202020",

Some files were not shown because too many files have changed in this diff Show More