From c144c149e67aa23a8c16d6813e74a6dc7d0567b5 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 11 Apr 2015 14:01:25 +0300 Subject: [PATCH] Class VPoster. --HG-- branch : feature --- src/app/core/vapplication.h | 2 +- src/app/options.h | 1 + src/libs/ifc/exception/vexception.cpp | 1 + src/libs/ifc/ifcdef.h | 58 ----- src/libs/vlayout/share/icons.qrc | 6 + .../vlayout/share/scissors_horizontal.png | Bin 0 -> 696 bytes src/libs/vlayout/share/scissors_vertical.png | Bin 0 -> 726 bytes src/libs/vlayout/vlayout.pri | 6 +- src/libs/vlayout/vlayout.pro | 5 +- src/libs/vlayout/vposter.cpp | 239 ++++++++++++++++++ src/libs/vlayout/vposter.h | 60 +++++ src/utils/def.h | 92 +++++++ src/utils/utils.pri | 3 +- 13 files changed, 410 insertions(+), 63 deletions(-) create mode 100644 src/libs/vlayout/share/icons.qrc create mode 100644 src/libs/vlayout/share/scissors_horizontal.png create mode 100644 src/libs/vlayout/share/scissors_vertical.png create mode 100644 src/libs/vlayout/vposter.cpp create mode 100644 src/libs/vlayout/vposter.h create mode 100644 src/utils/def.h 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 0000000000000000000000000000000000000000..3f732e4ce5f7065c1878eb6541df281679369327 GIT binary patch literal 696 zcmV;p0!RIcP))9Kyt;qCU5-%_t}NjhP3*fK6ygu%EH512%K84ol0_;9o@zHiv-%E@PVi44b050jLDcv%{5aesS+T^La<=A_P6VlkfL8XjOs z-qHbi6+Tsiwb{6xcXVyh`U2bxiyNwy(&hQDox#A8y{)Oa6KVRtp|%Txdz+Rr3FAxl zT9VFQ<^F)|Nb(CvhpCf-c8ooK1bbPE&rI`NcAfb~(miUzA#i eK#nKfW$_D&Hmgp2R_U4m00002>*!C zxhU{fj4J>y3VaYpqT+I$OfldZ{0{gZoW#F!^o5$lUpp!2OBO$D@pE%W>;t zAx9?he2@14?v?^S6B=hyPsw078?vOqcgmr6HgHM!gJNLGsv5v;OvkcBwv0wMo|by^ z33!*fbr1HI3Lb-pIRg0=drBRqPZGf1cry5mox{~Qdq!e6rr~2$WNT=>Fjj&Nyoo|u ziRG9SlKm|-{s(Y5VP6(MkO}`L9EzZJ<7L#t;-SFpQH@P0-&%A9{C#XoA8;Kn!rqc^ z0N0}}D)DfRsl7j;|66RwL^R@7*iYmul$L0pXLI;x<9+~crhFUm1#i+buMR6BP*r)h zpe|g>GX%Qu9CMS#&A5SQiSG6uQ**$V#3tH_^$GjBfPcuQTLUg)bp)d~(q}}ZTzd-q zBlO-9DOeo=+lN)SnjMx`;)bUpUDn`S*xK@B&kQujclu)O%|x4Blm&O=S8D5-g;(Kg z%mbf-UAPdJYr?$bc>fvTbkArG-;M$mJUP1J$n+-kETLKU^kZhcdkTO*M{EX_^VZO( zBl^UA90=%Jj4h>Ao=o)K*C9cFXjpQC--dhmglpK4)NMHDKT4&opA= + ** @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