From cdf3d76930f9eaa1def77dcfd29d2c47ea8b1511 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Fri, 17 Jun 2016 17:56:15 +0300 Subject: [PATCH] Fixed issue #494. Printing is not working. --HG-- branch : release --- ChangeLog.txt | 1 + src/app/valentina/mainwindow.cpp | 2 - src/app/valentina/mainwindow.ui | 19 -- src/app/valentina/mainwindowsnogui.cpp | 300 ++++++++++++++++--------- src/app/valentina/mainwindowsnogui.h | 11 +- src/libs/vlayout/vposter.cpp | 212 +++++++++-------- src/libs/vlayout/vposter.h | 31 ++- src/libs/vmisc/def.cpp | 4 +- src/libs/vmisc/def.h | 4 +- src/test/ValentinaTest/tst_vposter.cpp | 21 +- src/test/ValentinaTest/tst_vposter.h | 2 +- 11 files changed, 354 insertions(+), 253 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 77da4ea7e..4e363ce55 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -8,6 +8,7 @@ - [#468] Error - Tape 'Save As' should set 'Read Only' to false. - [#501] Rename Window->Close Window to Window->Close pattern. - [#515] Seam allowance wrong way. +- [#494] Printing is not working. # Version 0.4.4 April 12, 2016 - Updated measurement templates with all measurements. Added new template Aldrich/Women measurements. diff --git a/src/app/valentina/mainwindow.cpp b/src/app/valentina/mainwindow.cpp index 333f17c50..d3682fd08 100644 --- a/src/app/valentina/mainwindow.cpp +++ b/src/app/valentina/mainwindow.cpp @@ -2900,7 +2900,6 @@ void MainWindow::SetLayoutModeActions(bool enable) ui->actionExportAs->setEnabled(value); ui->actionPrintPreview->setEnabled(value); ui->actionPrintPreviewTiled->setEnabled(value); - ui->actionSaveAsPDF->setEnabled(value); ui->actionSaveAsTiledPDF->setEnabled(value); ui->actionPrint->setEnabled(value); ui->actionPrintTiled->setEnabled(value); @@ -3347,7 +3346,6 @@ void MainWindow::CreateActions() connect(ui->actionExportAs, &QAction::triggered, this, &MainWindow::ExportLayoutAs); connect(ui->actionPrintPreview, &QAction::triggered, this, &MainWindow::PrintPreviewOrigin); connect(ui->actionPrintPreviewTiled, &QAction::triggered, this, &MainWindow::PrintPreviewTiled); - connect(ui->actionSaveAsPDF, &QAction::triggered, this, &MainWindow::SaveAsPDF); connect(ui->actionSaveAsTiledPDF, &QAction::triggered, this, &MainWindow::SaveAsTiledPDF); connect(ui->actionPrint, &QAction::triggered, this, &MainWindow::PrintOrigin); connect(ui->actionPrintTiled, &QAction::triggered, this, &MainWindow::PrintTiled); diff --git a/src/app/valentina/mainwindow.ui b/src/app/valentina/mainwindow.ui index 0e8cab612..9d901d5ce 100644 --- a/src/app/valentina/mainwindow.ui +++ b/src/app/valentina/mainwindow.ui @@ -1040,7 +1040,6 @@ Layout - @@ -1887,24 +1886,6 @@ QAction::NoRole - - - false - - - - :/icon/32x32/pdf.png:/icon/32x32/pdf.png - - - Save as PDF - - - Save original layout - - - - - false diff --git a/src/app/valentina/mainwindowsnogui.cpp b/src/app/valentina/mainwindowsnogui.cpp index cf8cdc167..d56a69887 100644 --- a/src/app/valentina/mainwindowsnogui.cpp +++ b/src/app/valentina/mainwindowsnogui.cpp @@ -269,19 +269,6 @@ void MainWindowsNoGUI::ExportLayout(const DialogSaveLayout &dialog) } } -//--------------------------------------------------------------------------------------------------------------------- -void MainWindowsNoGUI::SaveAsPDF() -{ - if (not isPagesUniform()) - { - qCritical()< images = AllSheets(); - - QVector poster; - if (isTiled) - { - VPoster posterazor(printer); - for (int i=0; i < images.size(); i++) - { - poster += posterazor.Generate(images.at(i), i+1, images.size()); - } - } - else - { - poster = images; - } + // Here we try understand difference between printer's dpi and our. + // Get printer rect acording to our dpi. + const QRectF printerPageRect(0, 0, ToPixel(printer->pageRect(QPrinter::Millimeter).width(), Unit::Mm), + ToPixel(printer->pageRect(QPrinter::Millimeter).height(), Unit::Mm)); + const double xscale = printer->pageRect().width() / printerPageRect.width(); + const double yscale = printer->pageRect().height() / printerPageRect.height(); + const double scale = qMin(xscale, yscale); QPainter painter; if (not painter.begin(printer)) @@ -320,9 +294,40 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer) return; } + painter.setFont( QFont( "Arial", 8, QFont::Normal ) ); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setPen(QPen(Qt::black, qApp->toPixel(WidthMainLine(*pattern->GetPatternUnit())), Qt::SolidLine, + Qt::RoundCap, Qt::RoundJoin)); + painter.setBrush ( QBrush ( Qt::NoBrush ) ); + + int count = 0; + QSharedPointer> poster; + QSharedPointer posterazor; + + if (isTiled) + { + poster = QSharedPointer>(new QVector()); + posterazor = QSharedPointer(new VPoster(printer)); + + for (int i=0; i < scenes.size(); ++i) + { + auto *paper = qgraphicsitem_cast(papers.at(i)); + if (paper) + { + *poster += posterazor->Calc(paper->rect().toRect(), i); + } + } + + count = poster->size(); + } + else + { + count = scenes.size(); + } + // Handle the fromPage(), toPage(), supportsMultipleCopies(), and numCopies() values from QPrinter. int firstPage = printer->fromPage() - 1; - if (firstPage >= poster.size()) + if (firstPage >= count) { return; } @@ -332,9 +337,9 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer) } int lastPage = printer->toPage() - 1; - if (lastPage == -1 || lastPage >= poster.size()) + if (lastPage == -1 || lastPage >= count) { - lastPage = poster.size() - 1; + lastPage = count - 1; } const int numPages = lastPage - firstPage + 1; @@ -365,7 +370,38 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer) { index = lastPage - j; } - painter.drawImage(QPointF(margins.left(), margins.top()), poster.at(index)); + + int paperIndex = -1; + isTiled ? paperIndex = poster->at(index).index : paperIndex = index; + + auto *paper = qgraphicsitem_cast(papers.at(paperIndex)); + if (paper) + { + QVector posterData; + if (isTiled) + { + // Draw borders + posterData = posterazor->Borders(paper, poster->at(index), scenes.size()); + } + + PreparePaper(paperIndex); + + // Render + QRectF source; + isTiled ? source = poster->at(index).rect : source = paper->rect(); + QRectF target(0, 0, source.width() * scale, source.height() * scale); + + scenes.at(paperIndex)->render(&painter, target, source, Qt::IgnoreAspectRatio); + + if (isTiled) + { + // Remove borders + qDeleteAll(posterData); + } + + // Restore + RestorePaper(paperIndex); + } } } @@ -741,46 +777,31 @@ void MainWindowsNoGUI::DxfFile(const QString &name, int i) const #endif //--------------------------------------------------------------------------------------------------------------------- -QVector MainWindowsNoGUI::AllSheets() const +void MainWindowsNoGUI::PreparePaper(int index) const { - QVector images; - for (int i=0; i < scenes.size(); ++i) + auto *paper = qgraphicsitem_cast(papers.at(index)); + if (paper) { - QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(i)); - if (paper) - { - // Hide shadow and paper border - QBrush *brush = new QBrush(); - brush->setColor( QColor( Qt::white ) ); - scenes[i]->setBackgroundBrush( *brush ); - shadows[i]->setVisible(false); - paper->setPen(QPen(Qt::white, 0.1, Qt::NoPen));// border - - // Render png - const QRectF r = paper->rect(); - // Create the image with the exact size of the shrunk scene - QImage image(QSize(static_cast(r.width()), static_cast(r.height())), QImage::Format_RGB32); - image.fill(Qt::white); - QPainter painter(&image); - painter.setFont( QFont( "Arial", 8, QFont::Normal ) ); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setPen(QPen(Qt::black, qApp->toPixel(WidthMainLine(*pattern->GetPatternUnit())), Qt::SolidLine, - Qt::RoundCap, Qt::RoundJoin)); - painter.setBrush ( QBrush ( Qt::NoBrush ) ); - scenes.at(i)->render(&painter, r, r, Qt::IgnoreAspectRatio); - painter.end(); - images.append(image); - - // Resore - paper->setPen(QPen(Qt::black, qApp->toPixel(WidthMainLine(*pattern->GetPatternUnit())))); - brush->setColor( QColor( Qt::gray ) ); - brush->setStyle( Qt::SolidPattern ); - scenes[i]->setBackgroundBrush( *brush ); - shadows[i]->setVisible(true); - delete brush; - } + QBrush brush(Qt::white); + scenes.at(index)->setBackgroundBrush(brush); + shadows.at(index)->setVisible(false); + paper->setPen(QPen(Qt::white, 0.1, Qt::NoPen));// border + } + +} + +//--------------------------------------------------------------------------------------------------------------------- +void MainWindowsNoGUI::RestorePaper(int index) const +{ + auto *paper = qgraphicsitem_cast(papers.at(index)); + if (paper) + { + // Restore + paper->setPen(QPen(Qt::black, qApp->toPixel(WidthMainLine(*pattern->GetPatternUnit())))); + QBrush brush(Qt::gray); + scenes.at(index)->setBackgroundBrush(brush); + shadows.at(index)->setVisible(true); } - return images; } //--------------------------------------------------------------------------------------------------------------------- @@ -794,8 +815,13 @@ void MainWindowsNoGUI::SaveLayoutAs() } } QPrinter printer; - SetPrinterSettings(&printer); - printer.setOutputFormat(QPrinter::PdfFormat); + SetPrinterSettings(&printer, PrintType::PrintPDF); + + // Call IsPagesFit after setting a printer settings and check if pages is not bigger than printer's paper size + if (not isTiled && not IsPagesFit(printer.paperRect().size())) + { + qWarning()<ValentinaSettings()->GetPathLayout()+"/"+FileName()+".pdf", @@ -834,9 +860,10 @@ void MainWindowsNoGUI::PrintPreview() return; } - SetPrinterSettings(printer.data(), false); + SetPrinterSettings(printer.data(), PrintType::PrintPreview); + printer->setResolution(static_cast(PrintDPI)); // display print preview dialog - QPrintPreviewDialog preview(printer.data()); + QPrintPreviewDialog preview(printer.data()); connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindowsNoGUI::PrintPages); preview.exec(); } @@ -852,40 +879,42 @@ void MainWindowsNoGUI::LayoutPrint() } } // display print dialog and if accepted print - QPrinter printer(QPrinter::HighResolution); - SetPrinterSettings(&printer); - QPrintDialog dialog( &printer, this ); + QSharedPointer printer = DefaultPrinter(QPrinter::HighResolution); + if (printer.isNull()) + { + qCritical("%s\n\n%s", qUtf8Printable(tr("Print error")), + qUtf8Printable(tr("Cannot proceed because there are no available printers in your system."))); + return; + } + + SetPrinterSettings(printer.data(), PrintType::PrintNative); + QPrintDialog dialog(printer.data(), this ); // If only user couldn't change page margins we could use method setMinMax(); dialog.setOption(QPrintDialog::PrintCurrentPage, false); if ( dialog.exec() == QDialog::Accepted ) { - printer.setResolution(static_cast(PrintDPI)); - PrintPages( &printer ); + printer->setResolution(static_cast(PrintDPI)); + PrintPages(printer.data()); } } //--------------------------------------------------------------------------------------------------------------------- -void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, bool prepareForPrinting) +void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &printType) { SCASSERT(printer != nullptr) printer->setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion()); // Set orientation - if (papers.size() > 0) + if (paperSize.height() >= paperSize.width()) { - QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(0)); - SCASSERT(paper != nullptr) - if (paper->rect().height()>= paper->rect().width()) - { - printer->setOrientation(QPrinter::Portrait); - } - else - { - printer->setOrientation(QPrinter::Landscape); - } + printer->setOrientation(QPrinter::Portrait); + } + else + { + printer->setOrientation(QPrinter::Landscape); } - if (not isTiled && papers.size() > 0) + if (not isTiled) { const QSizeF size = QSizeF(FromPixel(paperSize.width(), Unit::Mm), FromPixel(paperSize.height(), Unit::Mm)); const QPrinter::PageSize pSZ = FindTemplate(size); @@ -907,14 +936,33 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, bool prepareForPrin printer->setPageMargins(left, top, right, bottom, QPrinter::Millimeter); } - if (prepareForPrinting) + switch(printType) { - #ifdef Q_OS_WIN - printer->setOutputFileName(QDir::homePath() + QDir::separator() + FileName()); - #else - printer->setOutputFileName(QDir::homePath() + QDir::separator() + FileName() + QLatin1Literal(".pdf")); - #endif + case PrintType::PrintPDF: + { + const QString outputFileName = QDir::homePath() + QDir::separator() + FileName(); + #ifdef Q_OS_WIN + printer->setOutputFileName(outputFileName); + #else + printer->setOutputFileName(outputFileName + QLatin1Literal(".pdf")); + #endif + + #ifdef Q_OS_MAC + printer->setOutputFormat(QPrinter::NativeFormat); + #else + printer->setOutputFormat(QPrinter::PdfFormat); + #endif + break; + } + case PrintType::PrintNative: + printer->setOutputFileName("");//Disable printing to file if was enabled. + printer->setOutputFormat(QPrinter::NativeFormat); + break; + case PrintType::PrintPreview: /*do nothing*/ + default: + break; } + printer->setDocName(FileName()); IsLayoutGrayscale() ? printer->setColorMode(QPrinter::GrayScale) : printer->setColorMode(QPrinter::Color); @@ -923,13 +971,33 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, bool prepareForPrin //--------------------------------------------------------------------------------------------------------------------- bool MainWindowsNoGUI::IsLayoutGrayscale() const { - const QVector images = AllSheets(); + const QRect target = QRect(0, 0, 100, 100);//Small image less memory need - for(int i=0; i < images.size(); ++i) + for (int i=0; i < scenes.size(); ++i) { - if (not images.at(i).isGrayscale()) + auto *paper = qgraphicsitem_cast(papers.at(i)); + if (paper) { - return false; + // Hide shadow and paper border + PreparePaper(i); + + // Render png + QImage image(target.size(), QImage::Format_RGB32); + image.fill(Qt::white); + QPainter painter(&image); + painter.setPen(QPen(Qt::black, qApp->toPixel(WidthMainLine(*pattern->GetPatternUnit())), Qt::SolidLine, + Qt::RoundCap, Qt::RoundJoin)); + painter.setBrush ( QBrush ( Qt::NoBrush ) ); + scenes.at(i)->render(&painter, target, paper->rect(), Qt::KeepAspectRatio); + painter.end(); + + // Restore + RestorePaper(i); + + if (not image.isGrayscale()) + { + return false; + } } } @@ -986,11 +1054,11 @@ bool MainWindowsNoGUI::isPagesUniform() const } else { - QGraphicsRectItem *paper = qgraphicsitem_cast(papers.at(0)); + auto *paper = qgraphicsitem_cast(papers.at(0)); SCASSERT(paper != nullptr) for (int i=1; i < papers.size(); ++i) { - QGraphicsRectItem *p = qgraphicsitem_cast(papers.at(i)); + auto *p = qgraphicsitem_cast(papers.at(i)); SCASSERT(p != nullptr) if (paper->rect() != p->rect()) { @@ -1001,6 +1069,22 @@ bool MainWindowsNoGUI::isPagesUniform() const return true; } +//--------------------------------------------------------------------------------------------------------------------- +bool MainWindowsNoGUI::IsPagesFit(const QSizeF &printPaper) const +{ + // On previous stage already was checked if pages have uniform size + // Enough will be to check only one page + QGraphicsRectItem *p = qgraphicsitem_cast(papers.at(0)); + SCASSERT(p != nullptr); + const QSizeF pSize = p->rect().size(); + if (pSize.height() <= printPaper.height() && pSize.width() <= printPaper.width()) + { + return true; + } + + return false; +} + //--------------------------------------------------------------------------------------------------------------------- QString MainWindowsNoGUI::FileName() const { diff --git a/src/app/valentina/mainwindowsnogui.h b/src/app/valentina/mainwindowsnogui.h index 63ab1e799..7ef8a7089 100644 --- a/src/app/valentina/mainwindowsnogui.h +++ b/src/app/valentina/mainwindowsnogui.h @@ -41,7 +41,7 @@ class QGraphicsScene; class QPrinter; - +class PosterData; class MainWindowsNoGUI : public QMainWindow { @@ -53,7 +53,6 @@ public: public slots: void ToolLayoutSettings(bool checked); void ExportLayoutAs(); - void SaveAsPDF(); void SaveAsTiledPDF(); void PrintPages (QPrinter *printer); void PrintPreviewOrigin(); @@ -116,17 +115,21 @@ private: void ObjFile(const QString &name, int i)const; void DxfFile(const QString &name, int i)const; - QVector AllSheets() const; + void PreparePaper(int index) const; + void RestorePaper(int index) const; void SaveLayoutAs(); void PrintPreview(); void LayoutPrint(); - void SetPrinterSettings(QPrinter *printer, bool prepareForPrinting = true); + enum class PrintType : char {PrintPDF, PrintPreview, PrintNative}; + + void SetPrinterSettings(QPrinter *printer, const PrintType &printType); bool IsLayoutGrayscale() const; QPrinter::PaperSize FindTemplate(const QSizeF &size) const; bool isPagesUniform() const; + bool IsPagesFit(const QSizeF &printPaper) const; QString FileName() const; int ContinueIfLayoutStale(); diff --git a/src/libs/vlayout/vposter.cpp b/src/libs/vlayout/vposter.cpp index f26c36f0c..6347e58e4 100644 --- a/src/libs/vlayout/vposter.cpp +++ b/src/libs/vlayout/vposter.cpp @@ -27,8 +27,9 @@ *************************************************************************/ #include "vposter.h" -#include #include +#include +#include #if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) # include "../vmisc/vmath.h" @@ -40,36 +41,126 @@ //--------------------------------------------------------------------------------------------------------------------- VPoster::VPoster(const QPrinter *printer) - :printer(printer), allowence(static_cast(qRound(10./25.4*printer->resolution())))//1 cm + :printer(printer), allowence(static_cast(qRound(10./25.4*PrintDPI)))//1 cm { } //--------------------------------------------------------------------------------------------------------------------- -QVector VPoster::Generate(const QImage &image, int page, int sheets) const +QVector VPoster::Calc(const QRect &imageRect, int page) const { - QVector poster; + QVector poster; if (printer == nullptr) { return poster; } - const int rows = CountRows(image.rect().height()); - const int colomns = CountColomns(image.rect().width()); + const int rows = CountRows(imageRect.height()); + const int columns = CountColumns(imageRect.width()); for (int i=0; i < rows; i++) { - for (int j=0; j< colomns; j++) + for (int j=0; j< columns; j++) { - QImage img = Cut(i, j, image); - img = Borders(rows, colomns, i, j, img, page, sheets); - poster.append(img); + PosterData data = Cut(i, j, imageRect); + data.index = page; + data.rows = rows; + data.columns = columns; + poster.append(data); } } return poster; } +//--------------------------------------------------------------------------------------------------------------------- +QVector VPoster::Borders(QGraphicsItem *parent, const PosterData &img, int sheets) const +{ + QVector data; + QPen pen(Qt::NoBrush, 1, Qt::DashLine); + pen.setColor(Qt::black); + + const QRect rec = img.rect; + if (img.column != 0) + {// Left border + auto *line = new QGraphicsLineItem(parent); + line->setPen(pen); + line->setLine(rec.x(), rec.y(), rec.x(), rec.y() + rec.height()); + data.append(line); + + auto *scissors = new QGraphicsPixmapItem(QPixmap("://scissors_vertical.png"), parent); + scissors->setPos(rec.x(), rec.y() + rec.height()-static_cast(allowence)); + data.append(scissors); + } + + if (img.column != img.columns-1) + {// Right border + auto *line = new QGraphicsLineItem(parent); + line->setPen(pen); + line->setLine(rec.x() + rec.width()-static_cast(allowence), rec.y(), + rec.x() + rec.width()-static_cast(allowence), rec.y() + rec.height()); + data.append(line); + } + + if (img.row != 0) + {// Top border + auto *line = new QGraphicsLineItem(parent); + line->setPen(pen); + line->setLine(rec.x(), rec.y(), rec.x() + rec.width(), rec.y()); + data.append(line); + + auto *scissors = new QGraphicsPixmapItem(QPixmap("://scissors_horizontal.png"), parent); + scissors->setPos(rec.x() + rec.width()-static_cast(allowence), rec.y()); + data.append(scissors); + } + + if (img.rows*img.columns > 1) + { // Don't show bottom border if only one page need + // Bottom border (mandatory) + auto *line = new QGraphicsLineItem(parent); + line->setPen(pen); + line->setLine(rec.x(), rec.y() + rec.height()-static_cast(allowence), + rec.x() + rec.width(), rec.y() + rec.height()-static_cast(allowence)); + data.append(line); + + if (img.row == img.rows-1) + { + auto *scissors = new QGraphicsPixmapItem(QPixmap("://scissors_horizontal.png"), parent); + scissors->setPos(rec.x() + rec.width()-static_cast(allowence), + rec.y() + rec.height()-static_cast(allowence)); + data.append(scissors); + } + } + + // Labels + auto *labels = new QGraphicsTextItem(parent); + + const int layoutX = 15; + const int layoutY = 5; + labels->setPos(rec.x() + layoutX, rec.y() + rec.height()-static_cast(allowence)+layoutY); + labels->setTextWidth(rec.width()-(static_cast(allowence)+layoutX)); + + const QString grid = tr("Grid ( %1 , %2 )").arg(img.row+1).arg(img.column+1); + const QString page = tr("Page %1 of %2").arg(img.row*(img.columns)+img.column+1).arg(img.rows*img.columns); + + QString sheet; + if (sheets > 1) + { + sheet = tr("Sheet %1 of %2").arg(img.index+1).arg(sheets); + } + + labels->setHtml(QString("" + "" + "" + "" + "
%1%2%3
") + .arg(grid, page, sheet)); + + data.append(labels); + + return data; +} + //--------------------------------------------------------------------------------------------------------------------- int VPoster::CountRows(int height) const { @@ -120,7 +211,7 @@ int VPoster::CountRows(int height) const } //--------------------------------------------------------------------------------------------------------------------- -int VPoster::CountColomns(int width) const +int VPoster::CountColumns(int width) const { const qreal imgLength = width; const qreal pageLength = PageRect().width(); @@ -148,96 +239,20 @@ int VPoster::CountColomns(int width) const } //--------------------------------------------------------------------------------------------------------------------- -QImage VPoster::Cut(int i, int j, const QImage &image) const +PosterData VPoster::Cut(int i, int j, const QRect &imageRect) const { const int x = j*PageRect().width() - j*static_cast(allowence); const int y = i*PageRect().height() - i*static_cast(allowence); - SCASSERT(x <= image.rect().width()); - SCASSERT(y <= image.rect().height()); + SCASSERT(x <= imageRect.width()); + SCASSERT(y <= imageRect.height()); - QRect copyRect(x, y, PageRect().width(), PageRect().height()); + PosterData data; + data.row = i; + data.column = j; + data.rect = QRect(x, y, PageRect().width(), PageRect().height()); - if (not image.rect().contains(copyRect)) - { - // Create full page with white background - QImage fullPage(copyRect.size(), image.format()); - fullPage.fill(Qt::white); - - // Real size that we can copy from image. - // Because in areas beyond the image, pixels are set to 0 by copy() method. - // For 32-bit RGB images, this means black. - 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 sheets) const -{ - QPainter painter(&image); - - QPen pen = QPen(Qt::NoBrush, 1, Qt::DashLine); - pen.setColor(Qt::black); - painter.setPen(pen); - - const QRect rec = image.rect(); - if (j != 0 && PageRect().x() > 0) - {// Left border - painter.drawLine(QLine(0, 0, 0, rec.height())); - painter.drawImage(QPoint(0, rec.height()-static_cast(allowence)), - QImage("://scissors_vertical.png")); - } - - if (j != colomns-1) - {// Right border - painter.drawLine(QLine(rec.width()-static_cast(allowence), 0, - rec.width()-static_cast(allowence), rec.height())); - } - - if (i != 0 && PageRect().y() > 0) - {// Top border - painter.drawLine(QLine(0, 0, rec.width(), 0)); - painter.drawImage(QPoint(rec.width()-static_cast(allowence), 0), - QImage("://scissors_horizontal.png")); - } - - if (rows*colomns > 1) - { // Don't show bottom border if only one page need - // Bottom border (mandatory) - painter.drawLine(QLine(0, rec.height()-static_cast(allowence), - rec.width(), rec.height()-static_cast(allowence))); - if (i == rows-1) - { - painter.drawImage(QPoint(rec.width()-static_cast(allowence), - rec.height()-static_cast(allowence)), - QImage("://scissors_horizontal.png")); - } - } - - // Labels - const int layoutX = 15; - const int layoutY = 5; - QRect labels(layoutX, rec.height()-static_cast(allowence)+layoutY, - rec.width()-(static_cast(allowence)+layoutX), static_cast(allowence)-layoutY); - painter.drawText(labels, Qt::AlignLeft, tr("Grid ( %1 , %2 )").arg(i+1).arg(j+1)); - painter.drawText(labels, Qt::AlignHCenter, tr("Page %1 of %2").arg(i*(colomns)+j+1).arg(rows*colomns)); - if (sheets > 1) - { - painter.drawText(labels, Qt::AlignRight, tr("Sheet %1 of %2").arg(page).arg(sheets)); - } - - painter.end(); - return image; + return data; } //--------------------------------------------------------------------------------------------------------------------- @@ -247,13 +262,12 @@ QRect VPoster::PageRect() const // we can't use method pageRect(QPrinter::Point). Our dpi value can be different. // We convert value yourself to pixels. const QRectF rect = printer->pageRect(QPrinter::Millimeter); - const QRect pageRect(qFloor(ToPixel(rect.x())), qFloor(ToPixel(rect.y())), qFloor(ToPixel(rect.width())), - qFloor(ToPixel(rect.height()))); + const QRect pageRect(0, 0, qFloor(ToPixel(rect.width())), qFloor(ToPixel(rect.height()))); return pageRect; } //--------------------------------------------------------------------------------------------------------------------- -qreal VPoster::ToPixel(qreal val) const +qreal VPoster::ToPixel(qreal val) { - return val / 25.4 * printer->resolution(); // Mm to pixels with current dpi. + return val / 25.4 * PrintDPI; // Mm to pixels with current dpi. } diff --git a/src/libs/vlayout/vposter.h b/src/libs/vlayout/vposter.h index 339e942d7..965f830bb 100644 --- a/src/libs/vlayout/vposter.h +++ b/src/libs/vlayout/vposter.h @@ -29,11 +29,29 @@ #ifndef VPOSTER_H #define VPOSTER_H -#include #include #include class QPrinter; +class QGraphicsItem; + +struct PosterData +{ + PosterData() + : index(0), + row(0), + column(0), + rows(0), + columns(0), + rect(){} + + quint32 index; // paper index + quint32 row; // positions in the greed + quint32 column; + quint32 rows; + quint32 columns; + QRect rect; // rect section +}; class VPoster { @@ -41,20 +59,21 @@ class VPoster public: explicit VPoster(const QPrinter *printer); - QVector Generate(const QImage &image, int page, int sheets = 1) const; + QVector Calc(const QRect &imageRect, int page) const; + + QVector Borders(QGraphicsItem *parent, const PosterData &img, int sheets) const; private: const QPrinter *printer; quint32 allowence; int CountRows(int height) const; - int CountColomns(int width) const; + int CountColumns(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 sheets) const; + PosterData Cut(int i, int j, const QRect &imageRect) const; QRect PageRect() const; - qreal ToPixel(qreal val) const; + static qreal ToPixel(qreal val); }; #endif // VPOSTER_H diff --git a/src/libs/vmisc/def.cpp b/src/libs/vmisc/def.cpp index 263d3328f..5175da808 100644 --- a/src/libs/vmisc/def.cpp +++ b/src/libs/vmisc/def.cpp @@ -1746,7 +1746,7 @@ QString AbsoluteMPath(const QString &patternPath, const QString &relativeMPath) } //--------------------------------------------------------------------------------------------------------------------- -QSharedPointer DefaultPrinter() +QSharedPointer DefaultPrinter(QPrinter::PrinterMode mode) { QPrinterInfo def = QPrinterInfo::defaultPrinter(); @@ -1763,7 +1763,7 @@ QSharedPointer DefaultPrinter() } } - QSharedPointer printer = QSharedPointer(new QPrinter(def, QPrinter::ScreenResolution)); + auto printer = QSharedPointer(new QPrinter(def, mode)); printer->setResolution(static_cast(PrintDPI)); return printer; } diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index 81c6b5343..dd0723c3b 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef Q_OS_WIN #include #endif /* Q_OS_WIN */ @@ -44,7 +45,6 @@ #endif /* Q_CC_MSVC */ class QComboBox; -class QPrinter; #define SceneSize 50000 #define DefPointRadius 1.5//mm @@ -598,7 +598,7 @@ QString StrippedName(const QString &fullFileName) Q_REQUIRED_RESULT; QString RelativeMPath(const QString &patternPath, const QString &absoluteMPath) Q_REQUIRED_RESULT; QString AbsoluteMPath(const QString &patternPath, const QString &relativeMPath) Q_REQUIRED_RESULT; -QSharedPointer DefaultPrinter() Q_REQUIRED_RESULT; +QSharedPointer DefaultPrinter(QPrinter::PrinterMode mode = QPrinter::ScreenResolution) Q_REQUIRED_RESULT; QPixmap darkenPixmap(const QPixmap &pixmap) Q_REQUIRED_RESULT; diff --git a/src/test/ValentinaTest/tst_vposter.cpp b/src/test/ValentinaTest/tst_vposter.cpp index d7ad28f91..cf1cc57e9 100644 --- a/src/test/ValentinaTest/tst_vposter.cpp +++ b/src/test/ValentinaTest/tst_vposter.cpp @@ -28,6 +28,7 @@ #include "tst_vposter.h" #include "../vlayout/vposter.h" +#include "../vmisc/def.h" #include #include @@ -47,15 +48,15 @@ void TST_VPoster::BigPoster() printer.setResolution(96);// By default printer.setPaperSize(QPrinter::A4); - const QImage image(2622, 3178, QImage::Format_RGB32); // Little bit bigger than A1 + const QRect image(0, 0, 2622, 3178); // Little bit bigger than A1 VPoster posterazor(&printer); - const QVector poster = posterazor.Generate(image, 1, 1); + const QVector poster = posterazor.Calc(image, 0); QCOMPARE(poster.size(), 16); for (int i=0; i < poster.size(); i++) { - QCOMPARE(poster.at(i).rect().size(), PageRect(printer).size()); + QCOMPARE(poster.at(i).rect.size(), PageRect(printer).size()); } } @@ -67,13 +68,13 @@ void TST_VPoster::SmallPoster() printer.setResolution(96);// By default printer.setPaperSize(QPrinter::A4); - const QImage image(700, 1000, QImage::Format_RGB32); // Little bit less than A4 + const QRect image(0, 0, 700, 1000); // Little bit less than A4 VPoster posterazor(&printer); - const QVector poster = posterazor.Generate(image, 1, 1); + const QVector poster = posterazor.Calc(image, 0); QCOMPARE(poster.size(), 1); - QCOMPARE(poster.at(0).rect().size(), PageRect(printer).size()); + QCOMPARE(poster.at(0).rect.size(), PageRect(printer).size()); } //--------------------------------------------------------------------------------------------------------------------- @@ -83,13 +84,13 @@ QRect TST_VPoster::PageRect(const QPrinter &printer) const // we can't use method pageRect(QPrinter::Point). Our dpi different can be different. // We convert value yourself to pixels. const QRectF rect = printer.pageRect(QPrinter::Millimeter); - QRect pageRect(qFloor(ToPixel(rect.x(), printer)), qFloor(ToPixel(rect.y(), printer)), - qFloor(ToPixel(rect.width(), printer)), qFloor(ToPixel(rect.height(), printer))); + QRect pageRect(qFloor(ToPixel(rect.x())), qFloor(ToPixel(rect.y())), + qFloor(ToPixel(rect.width())), qFloor(ToPixel(rect.height()))); return pageRect; } //--------------------------------------------------------------------------------------------------------------------- -qreal TST_VPoster::ToPixel(qreal val, const QPrinter &printer) const +qreal TST_VPoster::ToPixel(qreal val) const { - return val / 25.4 * printer.resolution(); // Mm to pixels with current dpi. + return val / 25.4 * PrintDPI; // Mm to pixels with current dpi. } diff --git a/src/test/ValentinaTest/tst_vposter.h b/src/test/ValentinaTest/tst_vposter.h index 6fd218d1f..8f40caf72 100644 --- a/src/test/ValentinaTest/tst_vposter.h +++ b/src/test/ValentinaTest/tst_vposter.h @@ -47,7 +47,7 @@ private slots: void SmallPoster(); private: - qreal ToPixel(qreal val, const QPrinter &printer) const; + qreal ToPixel(qreal val) const; QRect PageRect(const QPrinter &printer) const; };