Redesign printing system. ref #494. Printing is not working.
Made complete redesign of printing code. Now the code check printer's dpi and calculate scale factor. Instead of printing with QImage buffer the code print directly on printer. Help avoid limitations of QImage class. Also removed menu option "Save as PDF". The option duplicate option "Export As" and also mislead a user about purpose of option "Print preview". --HG-- branch : develop
This commit is contained in:
parent
00f854f1d9
commit
972dd36fcf
|
@ -3153,7 +3153,6 @@ void MainWindow::SetLayoutModeActions(bool enable)
|
||||||
ui->actionExportAs->setEnabled(value);
|
ui->actionExportAs->setEnabled(value);
|
||||||
ui->actionPrintPreview->setEnabled(value);
|
ui->actionPrintPreview->setEnabled(value);
|
||||||
ui->actionPrintPreviewTiled->setEnabled(value);
|
ui->actionPrintPreviewTiled->setEnabled(value);
|
||||||
ui->actionSaveAsPDF->setEnabled(value);
|
|
||||||
ui->actionSaveAsTiledPDF->setEnabled(value);
|
ui->actionSaveAsTiledPDF->setEnabled(value);
|
||||||
ui->actionPrint->setEnabled(value);
|
ui->actionPrint->setEnabled(value);
|
||||||
ui->actionPrintTiled->setEnabled(value);
|
ui->actionPrintTiled->setEnabled(value);
|
||||||
|
@ -3645,7 +3644,6 @@ void MainWindow::CreateActions()
|
||||||
connect(ui->actionExportAs, &QAction::triggered, this, &MainWindow::ExportLayoutAs);
|
connect(ui->actionExportAs, &QAction::triggered, this, &MainWindow::ExportLayoutAs);
|
||||||
connect(ui->actionPrintPreview, &QAction::triggered, this, &MainWindow::PrintPreviewOrigin);
|
connect(ui->actionPrintPreview, &QAction::triggered, this, &MainWindow::PrintPreviewOrigin);
|
||||||
connect(ui->actionPrintPreviewTiled, &QAction::triggered, this, &MainWindow::PrintPreviewTiled);
|
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->actionSaveAsTiledPDF, &QAction::triggered, this, &MainWindow::SaveAsTiledPDF);
|
||||||
connect(ui->actionPrint, &QAction::triggered, this, &MainWindow::PrintOrigin);
|
connect(ui->actionPrint, &QAction::triggered, this, &MainWindow::PrintOrigin);
|
||||||
connect(ui->actionPrintTiled, &QAction::triggered, this, &MainWindow::PrintTiled);
|
connect(ui->actionPrintTiled, &QAction::triggered, this, &MainWindow::PrintTiled);
|
||||||
|
|
|
@ -1189,7 +1189,6 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Layout</string>
|
<string>Layout</string>
|
||||||
</property>
|
</property>
|
||||||
<addaction name="actionSaveAsPDF"/>
|
|
||||||
<addaction name="actionPrintPreview"/>
|
<addaction name="actionPrintPreview"/>
|
||||||
<addaction name="actionPrint"/>
|
<addaction name="actionPrint"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
@ -2048,24 +2047,6 @@
|
||||||
<enum>QAction::NoRole</enum>
|
<enum>QAction::NoRole</enum>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSaveAsPDF">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../libs/vmisc/share/resources/icon.qrc">
|
|
||||||
<normaloff>:/icon/32x32/pdf.png</normaloff>:/icon/32x32/pdf.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Save as PDF</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Save original layout</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionSaveAsTiledPDF">
|
<action name="actionSaveAsTiledPDF">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
|
|
@ -266,19 +266,6 @@ void MainWindowsNoGUI::ExportLayout(const DialogSaveLayout &dialog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
|
||||||
void MainWindowsNoGUI::SaveAsPDF()
|
|
||||||
{
|
|
||||||
if (not isPagesUniform())
|
|
||||||
{
|
|
||||||
qCritical()<<tr("For saving multipage document all sheet should have the same size. Use export "
|
|
||||||
"function instead.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
isTiled = false;
|
|
||||||
SaveLayoutAs();
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void MainWindowsNoGUI::SaveAsTiledPDF()
|
void MainWindowsNoGUI::SaveAsTiledPDF()
|
||||||
{
|
{
|
||||||
|
@ -289,26 +276,13 @@ void MainWindowsNoGUI::SaveAsTiledPDF()
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
||||||
{
|
{
|
||||||
if (printer == nullptr)
|
// Here we try understand difference between printer's dpi and our.
|
||||||
{
|
// Get printer rect acording to our dpi.
|
||||||
return;
|
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 QVector<QImage> images = AllSheets(printer);
|
const double yscale = printer->pageRect().height() / printerPageRect.height();
|
||||||
|
const double scale = qMin(xscale, yscale);
|
||||||
QVector<QImage> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPainter painter;
|
QPainter painter;
|
||||||
if (not painter.begin(printer))
|
if (not painter.begin(printer))
|
||||||
|
@ -317,9 +291,40 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
||||||
return;
|
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<QVector<PosterData>> poster;
|
||||||
|
QSharedPointer<VPoster> posterazor;
|
||||||
|
|
||||||
|
if (isTiled)
|
||||||
|
{
|
||||||
|
poster = QSharedPointer<QVector<PosterData>>(new QVector<PosterData>());
|
||||||
|
posterazor = QSharedPointer<VPoster>(new VPoster(printer));
|
||||||
|
|
||||||
|
for (int i=0; i < scenes.size(); ++i)
|
||||||
|
{
|
||||||
|
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(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.
|
// Handle the fromPage(), toPage(), supportsMultipleCopies(), and numCopies() values from QPrinter.
|
||||||
int firstPage = printer->fromPage() - 1;
|
int firstPage = printer->fromPage() - 1;
|
||||||
if (firstPage >= poster.size())
|
if (firstPage >= count)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -329,9 +334,9 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastPage = printer->toPage() - 1;
|
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;
|
const int numPages = lastPage - firstPage + 1;
|
||||||
|
@ -362,7 +367,38 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
||||||
{
|
{
|
||||||
index = lastPage - j;
|
index = lastPage - j;
|
||||||
}
|
}
|
||||||
painter.drawImage(QPointF(), poster.at(index));
|
|
||||||
|
int paperIndex = -1;
|
||||||
|
isTiled ? paperIndex = poster->at(index).index : paperIndex = index;
|
||||||
|
|
||||||
|
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(paperIndex));
|
||||||
|
if (paper)
|
||||||
|
{
|
||||||
|
QVector<QGraphicsItem *> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,62 +774,31 @@ void MainWindowsNoGUI::DxfFile(const QString &name, int i) const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
QVector<QImage> MainWindowsNoGUI::AllSheets(const QPrinter *printer) const
|
void MainWindowsNoGUI::PreparePaper(int index) const
|
||||||
{
|
{
|
||||||
QVector<QImage> images;
|
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(index));
|
||||||
for (int i=0; i < scenes.size(); ++i)
|
if (paper)
|
||||||
{
|
{
|
||||||
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(i));
|
QBrush brush(Qt::white);
|
||||||
if (paper)
|
scenes.at(index)->setBackgroundBrush(brush);
|
||||||
{
|
shadows.at(index)->setVisible(false);
|
||||||
// Hide shadow and paper border
|
paper->setPen(QPen(Qt::white, 0.1, Qt::NoPen));// 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
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void MainWindowsNoGUI::RestorePaper(int index) const
|
||||||
// Render png
|
{
|
||||||
const QRectF source = paper->rect();
|
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(index));
|
||||||
QRectF target = source;
|
if (paper)
|
||||||
|
{
|
||||||
if (printer)
|
// Restore
|
||||||
{
|
paper->setPen(QPen(Qt::black, qApp->toPixel(WidthMainLine(*pattern->GetPatternUnit()))));
|
||||||
// Here we try understand difference between printer's dpi and our.
|
QBrush brush(Qt::gray);
|
||||||
// Get printer rect acording to our dpi.
|
scenes.at(index)->setBackgroundBrush(brush);
|
||||||
const QRectF printerPageRect(0, 0, ToPixel(printer->pageSizeMM().width(), Unit::Mm),
|
shadows.at(index)->setVisible(true);
|
||||||
ToPixel(printer->pageSizeMM().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);
|
|
||||||
target.setWidth(target.width() * scale);
|
|
||||||
target.setHeight(target.height() * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the image with the exact size of the shrunk scene
|
|
||||||
QImage image(QSize(static_cast<qint32>(target.width()), static_cast<qint32>(target.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, target, source, Qt::IgnoreAspectRatio);
|
|
||||||
painter.end();
|
|
||||||
images.append(image);
|
|
||||||
|
|
||||||
// Restore
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return images;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -855,7 +860,7 @@ void MainWindowsNoGUI::PrintPreview()
|
||||||
SetPrinterSettings(printer.data(), PrintType::PrintPreview);
|
SetPrinterSettings(printer.data(), PrintType::PrintPreview);
|
||||||
printer->setResolution(static_cast<int>(PrintDPI));
|
printer->setResolution(static_cast<int>(PrintDPI));
|
||||||
// display print preview dialog
|
// display print preview dialog
|
||||||
QPrintPreviewDialog preview(printer.data());
|
QPrintPreviewDialog preview(printer.data());
|
||||||
connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindowsNoGUI::PrintPages);
|
connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindowsNoGUI::PrintPages);
|
||||||
preview.exec();
|
preview.exec();
|
||||||
}
|
}
|
||||||
|
@ -897,21 +902,16 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &pr
|
||||||
printer->setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion());
|
printer->setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion());
|
||||||
|
|
||||||
// Set orientation
|
// Set orientation
|
||||||
if (papers.size() > 0)
|
if (paperSize.height() >= paperSize.width())
|
||||||
{
|
{
|
||||||
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(0));
|
printer->setOrientation(QPrinter::Portrait);
|
||||||
SCASSERT(paper != nullptr)
|
}
|
||||||
if (paper->rect().height()>= paper->rect().width())
|
else
|
||||||
{
|
{
|
||||||
printer->setOrientation(QPrinter::Portrait);
|
printer->setOrientation(QPrinter::Landscape);
|
||||||
}
|
|
||||||
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 QSizeF size = QSizeF(FromPixel(paperSize.width(), Unit::Mm), FromPixel(paperSize.height(), Unit::Mm));
|
||||||
const QPrinter::PageSize pSZ = FindTemplate(size);
|
const QPrinter::PageSize pSZ = FindTemplate(size);
|
||||||
|
@ -968,13 +968,33 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &pr
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
bool MainWindowsNoGUI::IsLayoutGrayscale() const
|
bool MainWindowsNoGUI::IsLayoutGrayscale() const
|
||||||
{
|
{
|
||||||
const QVector<QImage> 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<QGraphicsRectItem *>(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,11 +1051,11 @@ bool MainWindowsNoGUI::isPagesUniform() const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(0));
|
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(0));
|
||||||
SCASSERT(paper != nullptr)
|
SCASSERT(paper != nullptr)
|
||||||
for (int i=1; i < papers.size(); ++i)
|
for (int i=1; i < papers.size(); ++i)
|
||||||
{
|
{
|
||||||
QGraphicsRectItem *p = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(i));
|
auto *p = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(i));
|
||||||
SCASSERT(p != nullptr)
|
SCASSERT(p != nullptr)
|
||||||
if (paper->rect() != p->rect())
|
if (paper->rect() != p->rect())
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
class QGraphicsScene;
|
class QGraphicsScene;
|
||||||
class QPrinter;
|
class QPrinter;
|
||||||
|
class PosterData;
|
||||||
|
|
||||||
class MainWindowsNoGUI : public QMainWindow
|
class MainWindowsNoGUI : public QMainWindow
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,6 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void ToolLayoutSettings(bool checked);
|
void ToolLayoutSettings(bool checked);
|
||||||
void ExportLayoutAs();
|
void ExportLayoutAs();
|
||||||
void SaveAsPDF();
|
|
||||||
void SaveAsTiledPDF();
|
void SaveAsTiledPDF();
|
||||||
void PrintPages (QPrinter *printer);
|
void PrintPages (QPrinter *printer);
|
||||||
void PrintPreviewOrigin();
|
void PrintPreviewOrigin();
|
||||||
|
@ -117,7 +116,8 @@ private:
|
||||||
void ObjFile(const QString &name, int i)const;
|
void ObjFile(const QString &name, int i)const;
|
||||||
void DxfFile(const QString &name, int i)const;
|
void DxfFile(const QString &name, int i)const;
|
||||||
|
|
||||||
QVector<QImage> AllSheets(const QPrinter *printer = nullptr) const;
|
void PreparePaper(int index) const;
|
||||||
|
void RestorePaper(int index) const;
|
||||||
|
|
||||||
void SaveLayoutAs();
|
void SaveLayoutAs();
|
||||||
void PrintPreview();
|
void PrintPreview();
|
||||||
|
|
|
@ -27,8 +27,9 @@
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#include "vposter.h"
|
#include "vposter.h"
|
||||||
#include <QPainter>
|
|
||||||
#include <QPrinter>
|
#include <QPrinter>
|
||||||
|
#include <QGraphicsLineItem>
|
||||||
|
#include <QPen>
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0)
|
||||||
# include "../vmisc/vmath.h"
|
# include "../vmisc/vmath.h"
|
||||||
|
@ -40,36 +41,126 @@
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
VPoster::VPoster(const QPrinter *printer)
|
VPoster::VPoster(const QPrinter *printer)
|
||||||
:printer(printer), allowence(static_cast<quint32>(qRound(10./25.4*printer->resolution())))//1 cm
|
:printer(printer), allowence(static_cast<quint32>(qRound(10./25.4*PrintDPI)))//1 cm
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
QVector<QImage> VPoster::Generate(const QImage &image, int page, int sheets) const
|
QVector<PosterData> VPoster::Calc(const QRect &imageRect, int page) const
|
||||||
{
|
{
|
||||||
QVector<QImage> poster;
|
QVector<PosterData> poster;
|
||||||
|
|
||||||
if (printer == nullptr)
|
if (printer == nullptr)
|
||||||
{
|
{
|
||||||
return poster;
|
return poster;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int rows = CountRows(image.rect().height());
|
const int rows = CountRows(imageRect.height());
|
||||||
const int columns = CountColumns(image.rect().width());
|
const int columns = CountColumns(imageRect.width());
|
||||||
|
|
||||||
for (int i=0; i < rows; i++)
|
for (int i=0; i < rows; i++)
|
||||||
{
|
{
|
||||||
for (int j=0; j< columns; j++)
|
for (int j=0; j< columns; j++)
|
||||||
{
|
{
|
||||||
QImage img = Cut(i, j, image);
|
PosterData data = Cut(i, j, imageRect);
|
||||||
img = Borders(rows, columns, i, j, img, page, sheets);
|
data.index = page;
|
||||||
poster.append(img);
|
data.rows = rows;
|
||||||
|
data.columns = columns;
|
||||||
|
poster.append(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return poster;
|
return poster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
QVector<QGraphicsItem *> VPoster::Borders(QGraphicsItem *parent, const PosterData &img, int sheets) const
|
||||||
|
{
|
||||||
|
QVector<QGraphicsItem *> 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<int>(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<int>(allowence), rec.y(),
|
||||||
|
rec.x() + rec.width()-static_cast<int>(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<int>(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<int>(allowence),
|
||||||
|
rec.x() + rec.width(), rec.y() + rec.height()-static_cast<int>(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<int>(allowence),
|
||||||
|
rec.y() + rec.height()-static_cast<int>(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<int>(allowence)+layoutY);
|
||||||
|
labels->setTextWidth(rec.width()-(static_cast<int>(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("<table width='100%'>"
|
||||||
|
"<tr>"
|
||||||
|
"<td>%1</td><td align='center'>%2</td><td align='right'>%3</td>"
|
||||||
|
"</tr>"
|
||||||
|
"</table>")
|
||||||
|
.arg(grid, page, sheet));
|
||||||
|
|
||||||
|
data.append(labels);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
int VPoster::CountRows(int height) const
|
int VPoster::CountRows(int height) const
|
||||||
{
|
{
|
||||||
|
@ -148,96 +239,20 @@ int VPoster::CountColumns(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<int>(allowence);
|
const int x = j*PageRect().width() - j*static_cast<int>(allowence);
|
||||||
const int y = i*PageRect().height() - i*static_cast<int>(allowence);
|
const int y = i*PageRect().height() - i*static_cast<int>(allowence);
|
||||||
|
|
||||||
SCASSERT(x <= image.rect().width());
|
SCASSERT(x <= imageRect.width());
|
||||||
SCASSERT(y <= image.rect().height());
|
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))
|
return data;
|
||||||
{
|
|
||||||
// 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 columns, 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<int>(allowence)),
|
|
||||||
QImage("://scissors_vertical.png"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j != columns-1)
|
|
||||||
{// Right border
|
|
||||||
painter.drawLine(QLine(rec.width()-static_cast<int>(allowence), 0,
|
|
||||||
rec.width()-static_cast<int>(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<int>(allowence), 0),
|
|
||||||
QImage("://scissors_horizontal.png"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rows*columns > 1)
|
|
||||||
{ // Don't show bottom border if only one page need
|
|
||||||
// Bottom border (mandatory)
|
|
||||||
painter.drawLine(QLine(0, rec.height()-static_cast<int>(allowence),
|
|
||||||
rec.width(), rec.height()-static_cast<int>(allowence)));
|
|
||||||
if (i == rows-1)
|
|
||||||
{
|
|
||||||
painter.drawImage(QPoint(rec.width()-static_cast<int>(allowence),
|
|
||||||
rec.height()-static_cast<int>(allowence)),
|
|
||||||
QImage("://scissors_horizontal.png"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Labels
|
|
||||||
const int layoutX = 15;
|
|
||||||
const int layoutY = 5;
|
|
||||||
QRect labels(layoutX, rec.height()-static_cast<int>(allowence)+layoutY,
|
|
||||||
rec.width()-(static_cast<int>(allowence)+layoutX), static_cast<int>(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*(columns)+j+1).arg(rows*columns));
|
|
||||||
if (sheets > 1)
|
|
||||||
{
|
|
||||||
painter.drawText(labels, Qt::AlignRight, tr("Sheet %1 of %2").arg(page).arg(sheets));
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.end();
|
|
||||||
return image;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -247,13 +262,12 @@ QRect VPoster::PageRect() const
|
||||||
// we can't use method pageRect(QPrinter::Point). Our dpi value can be different.
|
// we can't use method pageRect(QPrinter::Point). Our dpi value can be different.
|
||||||
// We convert value yourself to pixels.
|
// We convert value yourself to pixels.
|
||||||
const QRectF rect = printer->pageRect(QPrinter::Millimeter);
|
const QRectF rect = printer->pageRect(QPrinter::Millimeter);
|
||||||
const QRect pageRect(qFloor(ToPixel(rect.x())), qFloor(ToPixel(rect.y())), qFloor(ToPixel(rect.width())),
|
const QRect pageRect(0, 0, qFloor(ToPixel(rect.width())), qFloor(ToPixel(rect.height())));
|
||||||
qFloor(ToPixel(rect.height())));
|
|
||||||
return pageRect;
|
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.
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,29 @@
|
||||||
#ifndef VPOSTER_H
|
#ifndef VPOSTER_H
|
||||||
#define VPOSTER_H
|
#define VPOSTER_H
|
||||||
|
|
||||||
#include <QImage>
|
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
class QPrinter;
|
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
|
class VPoster
|
||||||
{
|
{
|
||||||
|
@ -41,7 +59,9 @@ class VPoster
|
||||||
public:
|
public:
|
||||||
explicit VPoster(const QPrinter *printer);
|
explicit VPoster(const QPrinter *printer);
|
||||||
|
|
||||||
QVector<QImage> Generate(const QImage &image, int page, int sheets = 1) const;
|
QVector<PosterData> Calc(const QRect &imageRect, int page) const;
|
||||||
|
|
||||||
|
QVector<QGraphicsItem *> Borders(QGraphicsItem *parent, const PosterData &img, int sheets) const;
|
||||||
private:
|
private:
|
||||||
const QPrinter *printer;
|
const QPrinter *printer;
|
||||||
quint32 allowence;
|
quint32 allowence;
|
||||||
|
@ -49,12 +69,12 @@ private:
|
||||||
int CountRows(int height) const;
|
int CountRows(int height) const;
|
||||||
int CountColumns(int width) const;
|
int CountColumns(int width) const;
|
||||||
|
|
||||||
QImage Cut(int i, int j, const QImage &image) const;
|
PosterData Cut(int i, int j, const QRect &imageRect) const;
|
||||||
QImage Borders(int rows, int columns, int i, int j, QImage &image, int page, int sheets) const;
|
QImage Borders(int rows, int columns, int i, int j, QImage &image, int page, int sheets) const;
|
||||||
|
|
||||||
QRect PageRect() const;
|
QRect PageRect() const;
|
||||||
|
|
||||||
qreal ToPixel(qreal val) const;
|
static qreal ToPixel(qreal val);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VPOSTER_H
|
#endif // VPOSTER_H
|
||||||
|
|
|
@ -1767,7 +1767,7 @@ QSharedPointer<QPrinter> DefaultPrinter(QPrinter::PrinterMode mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<QPrinter> printer = QSharedPointer<QPrinter>(new QPrinter(def, mode));
|
auto printer = QSharedPointer<QPrinter>(new QPrinter(def, mode));
|
||||||
printer->setResolution(static_cast<int>(PrintDPI));
|
printer->setResolution(static_cast<int>(PrintDPI));
|
||||||
return printer;
|
return printer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "tst_vposter.h"
|
#include "tst_vposter.h"
|
||||||
#include "../vlayout/vposter.h"
|
#include "../vlayout/vposter.h"
|
||||||
|
#include "../vmisc/def.h"
|
||||||
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QPrinter>
|
#include <QPrinter>
|
||||||
|
@ -49,15 +50,15 @@ void TST_VPoster::BigPoster()
|
||||||
printer.setFullPage(true);
|
printer.setFullPage(true);
|
||||||
// We need to set full page because otherwise QPrinter->pageRect returns different values in Windows and Linux
|
// We need to set full page because otherwise QPrinter->pageRect returns different values in Windows and Linux
|
||||||
|
|
||||||
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);
|
VPoster posterazor(&printer);
|
||||||
const QVector<QImage> poster = posterazor.Generate(image, 1, 1);
|
const QVector<PosterData> poster = posterazor.Calc(image, 0);
|
||||||
|
|
||||||
QCOMPARE(poster.size(), 12);
|
QCOMPARE(poster.size(), 12);
|
||||||
|
|
||||||
for (int i=0; i < poster.size(); i++)
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,13 +70,13 @@ void TST_VPoster::SmallPoster()
|
||||||
printer.setResolution(96);// By default
|
printer.setResolution(96);// By default
|
||||||
printer.setPaperSize(QPrinter::A4);
|
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);
|
VPoster posterazor(&printer);
|
||||||
const QVector<QImage> poster = posterazor.Generate(image, 1, 1);
|
const QVector<PosterData> poster = posterazor.Calc(image, 0);
|
||||||
|
|
||||||
QCOMPARE(poster.size(), 1);
|
QCOMPARE(poster.size(), 1);
|
||||||
|
|
||||||
QCOMPARE(poster.at(0).rect().size(), PageRect(printer).size());
|
QCOMPARE(poster.at(0).rect.size(), PageRect(printer).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -85,13 +86,13 @@ QRect TST_VPoster::PageRect(const QPrinter &printer) const
|
||||||
// we can't use method pageRect(QPrinter::Point). Our dpi different can be different.
|
// we can't use method pageRect(QPrinter::Point). Our dpi different can be different.
|
||||||
// We convert value yourself to pixels.
|
// We convert value yourself to pixels.
|
||||||
const QRectF rect = printer.pageRect(QPrinter::Millimeter);
|
const QRectF rect = printer.pageRect(QPrinter::Millimeter);
|
||||||
QRect pageRect(qFloor(ToPixel(rect.x(), printer)), qFloor(ToPixel(rect.y(), printer)),
|
QRect pageRect(qFloor(ToPixel(rect.x())), qFloor(ToPixel(rect.y())),
|
||||||
qFloor(ToPixel(rect.width(), printer)), qFloor(ToPixel(rect.height(), printer)));
|
qFloor(ToPixel(rect.width())), qFloor(ToPixel(rect.height())));
|
||||||
return pageRect;
|
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.
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ private slots:
|
||||||
void SmallPoster();
|
void SmallPoster();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qreal ToPixel(qreal val, const QPrinter &printer) const;
|
qreal ToPixel(qreal val) const;
|
||||||
QRect PageRect(const QPrinter &printer) const;
|
QRect PageRect(const QPrinter &printer) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user