diff --git a/src/app/core/vapplication.h b/src/app/core/vapplication.h index e7f074944..da5df856d 100644 --- a/src/app/core/vapplication.h +++ b/src/app/core/vapplication.h @@ -279,7 +279,7 @@ inline void VApplication::setCurrentDocument(VPattern *doc) inline VPattern *VApplication::getCurrentDocument() const { SCASSERT(doc != nullptr) - return doc; + return doc; } #endif // VAPPLICATION_H diff --git a/src/app/options.h b/src/app/options.h index 57380992a..9ea81af9c 100644 --- a/src/app/options.h +++ b/src/app/options.h @@ -30,6 +30,7 @@ #define OPTIONS_H #include "../libs/ifc/ifcdef.h" +#include "../../utils/def.h" #ifdef Q_OS_WIN32 # if defined( Q_CC_MSVC ) // MSVC USED diff --git a/src/libs/ifc/exception/vexception.cpp b/src/libs/ifc/exception/vexception.cpp index 94dab8cfe..e1da1d3e1 100644 --- a/src/libs/ifc/exception/vexception.cpp +++ b/src/libs/ifc/exception/vexception.cpp @@ -28,6 +28,7 @@ #include "vexception.h" #include "../../../utils/logging.h" +#include "../../../utils/def.h" #include #include diff --git a/src/libs/ifc/ifcdef.h b/src/libs/ifc/ifcdef.h index a3d98ad03..506533397 100644 --- a/src/libs/ifc/ifcdef.h +++ b/src/libs/ifc/ifcdef.h @@ -29,7 +29,6 @@ #ifndef IFCDEF_H #define IFCDEF_H -#include #include #ifdef Q_OS_WIN32 @@ -45,63 +44,6 @@ static const quint32 null_id = 0; #define NULL_ID null_id//use this value for initialization variables that keeps id values. 0 mean uknown id value. #define NULL_ID_STR "0" -/* - * This macros SCASSERT (for Stop and Continue Assert) will break into the debugger on the line of the assert and allow - * you to continue afterwards should you choose to. - * idea: Q_ASSERT no longer pauses debugger - http://qt-project.org/forums/viewthread/13148 - * Usefull links: - * 1. What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? - - * https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func - * - * 2. Windows Predefined Macros - http://msdn.microsoft.com/library/b0084kay.aspx - * - * 3. Windows DebugBreak function - http://msdn.microsoft.com/en-us/library/ms679297%28VS.85%29.aspx - * - * 4. Continue to debug after failed assertion on Linux? [C/C++] - - * https://stackoverflow.com/questions/1721543/continue-to-debug-after-failed-assertion-on-linux-c-c - */ -#ifndef V_NO_ASSERT -#ifdef Q_OS_WIN32 -#ifdef Q_CC_MSVC -#define SCASSERT(cond) \ -{ \ - if (!(cond)) \ - { \ - qDebug("ASSERT: %s in %s (%s:%u)", \ - #cond, __FUNCSIG__, __FILE__, __LINE__); \ - DebugBreak(); \ - } \ -} \ - -#else // GCC (Windows) - -#define SCASSERT(cond) \ -{ \ - if (!(cond)) \ - { \ - qDebug("ASSERT: %s in %s (%s:%u)", \ - #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ - DebugBreak(); \ - } \ -} \ - -#endif /*Q_CC_MSVC*/ -#else // UNIX -#define SCASSERT(cond) \ -{ \ - if (!(cond)) \ - { \ - qDebug("ASSERT: %s in %s (%s:%u)", \ - #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ - std::raise(SIGTRAP); \ - } \ -} \ - -#endif /* Q_OS_WIN32 */ -#else // define but disable this function if debugging is not set -#define SCASSERT(cond) qt_noop(); -#endif /* V_NO_ASSERT */ - // Detect whether the compiler supports C++11 noexcept exception specifications. # if defined(__clang__) # if __has_feature(cxx_noexcept) diff --git a/src/libs/vlayout/share/icons.qrc b/src/libs/vlayout/share/icons.qrc new file mode 100644 index 000000000..daa859f6f --- /dev/null +++ b/src/libs/vlayout/share/icons.qrc @@ -0,0 +1,6 @@ + + + scissors_horizontal.png + scissors_vertical.png + + diff --git a/src/libs/vlayout/share/scissors_horizontal.png b/src/libs/vlayout/share/scissors_horizontal.png new file mode 100644 index 000000000..3f732e4ce Binary files /dev/null and b/src/libs/vlayout/share/scissors_horizontal.png differ diff --git a/src/libs/vlayout/share/scissors_vertical.png b/src/libs/vlayout/share/scissors_vertical.png new file mode 100644 index 000000000..2508af525 Binary files /dev/null and b/src/libs/vlayout/share/scissors_vertical.png differ diff --git a/src/libs/vlayout/vlayout.pri b/src/libs/vlayout/vlayout.pri index 65bebdf49..36aba3f20 100644 --- a/src/libs/vlayout/vlayout.pri +++ b/src/libs/vlayout/vlayout.pri @@ -15,7 +15,8 @@ HEADERS += \ $$PWD/vcontour.h \ $$PWD/vcontour_p.h \ $$PWD/vbestsquare.h \ - $$PWD/vposition.h + $$PWD/vposition.h \ + vposter.h SOURCES += \ $$PWD/stable.cpp \ @@ -26,4 +27,5 @@ SOURCES += \ $$PWD/vbank.cpp \ $$PWD/vcontour.cpp \ $$PWD/vbestsquare.cpp \ - $$PWD/vposition.cpp + $$PWD/vposition.cpp \ + vposter.cpp diff --git a/src/libs/vlayout/vlayout.pro b/src/libs/vlayout/vlayout.pro index 97fb5fe86..1e49cda60 100644 --- a/src/libs/vlayout/vlayout.pro +++ b/src/libs/vlayout/vlayout.pro @@ -7,7 +7,7 @@ # File with common stuff for whole project include(../../../Valentina.pri) -QT += core gui widgets +QT += core gui widgets printsupport # Name of library TARGET = vlayout @@ -93,3 +93,6 @@ CONFIG(debug, debug|release){ QMAKE_LFLAGS_RELEASE = } } + +RESOURCES += \ + share/icons.qrc diff --git a/src/libs/vlayout/vposter.cpp b/src/libs/vlayout/vposter.cpp new file mode 100644 index 000000000..6fb36b266 --- /dev/null +++ b/src/libs/vlayout/vposter.cpp @@ -0,0 +1,239 @@ +/************************************************************************ + ** + ** @file vposter.cpp + ** @author Roman Telezhynskyi + ** @date 11 4, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** 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 . + ** + *************************************************************************/ + +#include "vposter.h" +#include +#include +#include + +#include "../../utils/def.h" + +//--------------------------------------------------------------------------------------------------------------------- +VPoster::VPoster(const QPrinter *printer) + :printer(printer), allowence(38)//1 cm +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector VPoster::Generate(const QImage &image, int page, int pages) const +{ + QVector poster; + + if (printer == nullptr) + { + return poster; + } + + const int rows = CountRows(image.rect().height()); + const int colomns = CountColomns(image.rect().width()); + + for (int i=0; i < rows; i++) + { + for (int j=0; j< colomns; j++) + { + QImage img = Cut(i, j, image); + img = Borders(rows, colomns, i, j, img, page, pages); + poster.append(img); + } + } + + return poster; +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPoster::CountRows(int height) const +{ + const qreal imgLength = height; + const qreal pageLength = PageRect().height(); + + // Example + // ― ― + // * * + // * * + // * * + // * * ― + // ― ― * + // * * + // * * + // * * ― + // * ― * + // — * + // * * + // * * ― + // * ― * + // * * + // — * + // * * ― + // * ― * <-(2) + // * + * + // * + * + // — + * ― <-(4) + // ^ ^ ― * + //(3) (1) * + // * + // * + // ― + + const int pCount = qCeil(imgLength/pageLength);// Pages count without allowence (or allowence = 0) (3) + + // Calculate how many pages will be after using allowence. + // We know start pages count. This number not enought because + // each n-1 pages add (n-1)*allowence length to page (1). + const qreal addionalLength = (pCount-1)*allowence; + + // Calculate additional length form pages that will cover this length (2). + // In the end add page length (3). + // Bottom page have mandatory border (4) + return qCeil((addionalLength + + qCeil(addionalLength/pageLength)*allowence + allowence + imgLength)/pageLength); +} + +//--------------------------------------------------------------------------------------------------------------------- +int VPoster::CountColomns(int width) const +{ + const qreal imgLength = width; + const qreal pageLength = PageRect().width(); + + // Example + // |----|----|----|----| <- (3) + // |----|+++++++++++++++ + // |----|+++++++++++ + // |----|+++++++ + // |----|+++ <- (1) + // |----| + // ^ + // (2) + const int pCount = qCeil(imgLength/pageLength);// Pages count without allowence (or allowence = 0) (3) + + // Calculate how many pages will be after using allowence. + // We know start pages count. This number not enought because + // each n-1 pages add (n-1)*allowence length to page (1). + const qreal addionalLength = (pCount-1)*allowence; + + // Calculate additional length form pages that will cover this length (2). + // In the end add page length (3). + return qCeil((addionalLength + qCeil(addionalLength/pageLength)*allowence + imgLength)/pageLength); +} + +//--------------------------------------------------------------------------------------------------------------------- +QImage VPoster::Cut(int i, int j, const QImage &image) const +{ + const int x = j*PageRect().width() - j*allowence; + const int y = i*PageRect().height() - i*allowence; + + SCASSERT(x <= image.rect().width()); + SCASSERT(y <= image.rect().height()); + + QRect copyRect(x, y, PageRect().width(), PageRect().height()); + + if (not image.rect().contains(copyRect)) + { + QImage fullPage(copyRect.size(), image.format()); + fullPage.fill(Qt::white); + + copyRect = image.rect().intersected(copyRect); + + QPainter painter(&fullPage); + painter.drawImage(QPointF(), image.copy( copyRect)); + painter.end(); + + return fullPage; + } + else + { + return image.copy(copyRect); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +QImage VPoster::Borders(int rows, int colomns, int i, int j, QImage &image, int page, int pages) const +{ + QPainter painter(&image); + + QPen pen = QPen(Qt::NoBrush, 1, Qt::DashLine); + pen.setColor(Qt::black); + painter.setPen(pen); + + if (j != 0) + {// Left border + painter.drawLine(QLine(0, 0, 0, image.rect().height())); + painter.drawImage(QPoint(0, image.rect().height()-allowence), QImage("://scissors_vertical.png")); + } + + if (j != colomns-1) + {// Right border + painter.drawLine(QLine(image.rect().width()-allowence, 0, + image.rect().width()-allowence, image.rect().height())); + } + + if (i != 0) + {// Top border + painter.drawLine(QLine(0, 0, image.rect().width(), 0)); + painter.drawImage(QPoint(image.rect().width()-allowence, 0), QImage("://scissors_horizontal.png")); + } + + // Bottom border (mandatory) + painter.drawLine(QLine(0, image.rect().height()-allowence, + image.rect().width(), image.rect().height()-allowence)); + if (i == rows-1) + { + painter.drawImage(QPoint(image.rect().width()-allowence, image.rect().height()-allowence), + QImage("://scissors_horizontal.png")); + } + + // Labels + const int layoutX = 15; + const int layoutY = 5; + QRect labels(layoutX, image.rect().height()-allowence+layoutY, + image.rect().width()-(allowence+layoutX), allowence-layoutY); + painter.drawText(labels, Qt::AlignLeft, tr("Grid ( %1 , %2 )").arg(i).arg(j)); + painter.drawText(labels, Qt::AlignHCenter, tr("Page %1 of %2").arg(i*(colomns)+j+1).arg(rows*colomns)); + if (pages > 1) + { + painter.drawText(labels, Qt::AlignRight, tr("Sheet %1 of %2").arg(page).arg(pages)); + } + + painter.end(); + return image; +} + +//--------------------------------------------------------------------------------------------------------------------- +QRect VPoster::PageRect() const +{ + + const QRectF rect = printer->pageRect(QPrinter::Millimeter); + QRect pageRect(qFloor(ToPixel(rect.x())), qFloor(ToPixel(rect.y())), qFloor(ToPixel(rect.width())), + qFloor(ToPixel(rect.height()))); + return pageRect; +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal VPoster::ToPixel(qreal val) const +{ + return val / 25.4 * printer->resolution(); // Mm to pixels with current dpi. +} diff --git a/src/libs/vlayout/vposter.h b/src/libs/vlayout/vposter.h new file mode 100644 index 000000000..334358cf8 --- /dev/null +++ b/src/libs/vlayout/vposter.h @@ -0,0 +1,60 @@ +/************************************************************************ + ** + ** @file vposter.h + ** @author Roman Telezhynskyi + ** @date 11 4, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** 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 . + ** + *************************************************************************/ + +#ifndef VPOSTER_H +#define VPOSTER_H + +#include +#include +#include + +class QPrinter; + +class VPoster +{ + Q_DECLARE_TR_FUNCTIONS(VPoster) +public: + VPoster(const QPrinter *printer); + + QVector Generate(const QImage &image, int page, int pages = 1) const; +private: + const QPrinter *printer; + unsigned int allowence; + + int CountRows(int height) const; + int CountColomns(int width) const; + + QImage Cut(int i, int j, const QImage &image) const; + QImage Borders(int rows, int colomns, int i, int j, QImage &image, int page, int pages) const; + + QRect PageRect() const; + + qreal ToPixel(qreal val) const; +}; + +#endif // VPOSTER_H diff --git a/src/utils/def.h b/src/utils/def.h new file mode 100644 index 000000000..cd02e81c2 --- /dev/null +++ b/src/utils/def.h @@ -0,0 +1,92 @@ +/************************************************************************ + ** + ** @file def.h + ** @author Roman Telezhynskyi + ** @date 11 4, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** 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 . + ** + *************************************************************************/ + +#ifndef DEF_H +#define DEF_H + +#include +#include + +/* + * This macros SCASSERT (for Stop and Continue Assert) will break into the debugger on the line of the assert and allow + * you to continue afterwards should you choose to. + * idea: Q_ASSERT no longer pauses debugger - http://qt-project.org/forums/viewthread/13148 + * Usefull links: + * 1. What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? - + * https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func + * + * 2. Windows Predefined Macros - http://msdn.microsoft.com/library/b0084kay.aspx + * + * 3. Windows DebugBreak function - http://msdn.microsoft.com/en-us/library/ms679297%28VS.85%29.aspx + * + * 4. Continue to debug after failed assertion on Linux? [C/C++] - + * https://stackoverflow.com/questions/1721543/continue-to-debug-after-failed-assertion-on-linux-c-c + */ +#ifndef V_NO_ASSERT +#ifdef Q_OS_WIN32 +#ifdef Q_CC_MSVC +#define SCASSERT(cond) \ +{ \ + if (!(cond)) \ + { \ + qDebug("ASSERT: %s in %s (%s:%u)", \ + #cond, __FUNCSIG__, __FILE__, __LINE__); \ + DebugBreak(); \ + } \ +} \ + +#else // GCC (Windows) + +#define SCASSERT(cond) \ +{ \ + if (!(cond)) \ + { \ + qDebug("ASSERT: %s in %s (%s:%u)", \ + #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ + DebugBreak(); \ + } \ +} \ + +#endif /*Q_CC_MSVC*/ +#else // UNIX +#define SCASSERT(cond) \ +{ \ + if (!(cond)) \ + { \ + qDebug("ASSERT: %s in %s (%s:%u)", \ + #cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\ + std::raise(SIGTRAP); \ + } \ +} \ + +#endif /* Q_OS_WIN32 */ +#else // define but disable this function if debugging is not set +#define SCASSERT(cond) qt_noop(); +#endif /* V_NO_ASSERT */ + +#endif // DEF_H diff --git a/src/utils/utils.pri b/src/utils/utils.pri index 851661377..0fc1408a4 100644 --- a/src/utils/utils.pri +++ b/src/utils/utils.pri @@ -1,3 +1,4 @@ HEADERS += \ $$PWD/logging.h \ - $$PWD/vmath.h + $$PWD/vmath.h \ + $$PWD/def.h