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->actionPrintPreview->setEnabled(value);
|
||||
ui->actionPrintPreviewTiled->setEnabled(value);
|
||||
ui->actionSaveAsPDF->setEnabled(value);
|
||||
ui->actionSaveAsTiledPDF->setEnabled(value);
|
||||
ui->actionPrint->setEnabled(value);
|
||||
ui->actionPrintTiled->setEnabled(value);
|
||||
|
@ -3645,7 +3644,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);
|
||||
|
|
|
@ -1189,7 +1189,6 @@
|
|||
<property name="title">
|
||||
<string>Layout</string>
|
||||
</property>
|
||||
<addaction name="actionSaveAsPDF"/>
|
||||
<addaction name="actionPrintPreview"/>
|
||||
<addaction name="actionPrint"/>
|
||||
<addaction name="separator"/>
|
||||
|
@ -2048,24 +2047,6 @@
|
|||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</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">
|
||||
<property name="enabled">
|
||||
<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()
|
||||
{
|
||||
|
@ -289,26 +276,13 @@ void MainWindowsNoGUI::SaveAsTiledPDF()
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
||||
{
|
||||
if (printer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector<QImage> images = AllSheets(printer);
|
||||
|
||||
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;
|
||||
}
|
||||
// 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))
|
||||
|
@ -317,9 +291,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<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.
|
||||
int firstPage = printer->fromPage() - 1;
|
||||
if (firstPage >= poster.size())
|
||||
if (firstPage >= count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -329,9 +334,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;
|
||||
|
@ -362,7 +367,38 @@ void MainWindowsNoGUI::PrintPages(QPrinter *printer)
|
|||
{
|
||||
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,63 +774,32 @@ void MainWindowsNoGUI::DxfFile(const QString &name, int i) const
|
|||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
QVector<QImage> MainWindowsNoGUI::AllSheets(const QPrinter *printer) const
|
||||
void MainWindowsNoGUI::PreparePaper(int index) const
|
||||
{
|
||||
QVector<QImage> images;
|
||||
for (int i=0; i < scenes.size(); ++i)
|
||||
{
|
||||
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(i));
|
||||
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(index));
|
||||
if (paper)
|
||||
{
|
||||
// Hide shadow and paper border
|
||||
QBrush *brush = new QBrush();
|
||||
brush->setColor( QColor( Qt::white ) );
|
||||
scenes[i]->setBackgroundBrush( *brush );
|
||||
shadows[i]->setVisible(false);
|
||||
QBrush brush(Qt::white);
|
||||
scenes.at(index)->setBackgroundBrush(brush);
|
||||
shadows.at(index)->setVisible(false);
|
||||
paper->setPen(QPen(Qt::white, 0.1, Qt::NoPen));// border
|
||||
|
||||
// Render png
|
||||
const QRectF source = paper->rect();
|
||||
QRectF target = source;
|
||||
|
||||
if (printer)
|
||||
{
|
||||
// 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->pageSizeMM().width(), Unit::Mm),
|
||||
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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindowsNoGUI::RestorePaper(int index) const
|
||||
{
|
||||
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(index));
|
||||
if (paper)
|
||||
{
|
||||
// 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;
|
||||
QBrush brush(Qt::gray);
|
||||
scenes.at(index)->setBackgroundBrush(brush);
|
||||
shadows.at(index)->setVisible(true);
|
||||
}
|
||||
}
|
||||
return images;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
void MainWindowsNoGUI::SaveLayoutAs()
|
||||
|
@ -897,11 +902,7 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &pr
|
|||
printer->setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion());
|
||||
|
||||
// Set orientation
|
||||
if (papers.size() > 0)
|
||||
{
|
||||
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(0));
|
||||
SCASSERT(paper != nullptr)
|
||||
if (paper->rect().height()>= paper->rect().width())
|
||||
if (paperSize.height() >= paperSize.width())
|
||||
{
|
||||
printer->setOrientation(QPrinter::Portrait);
|
||||
}
|
||||
|
@ -909,9 +910,8 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &pr
|
|||
{
|
||||
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);
|
||||
|
@ -968,15 +968,35 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &pr
|
|||
//---------------------------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1031,11 +1051,11 @@ bool MainWindowsNoGUI::isPagesUniform() const
|
|||
}
|
||||
else
|
||||
{
|
||||
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(0));
|
||||
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(0));
|
||||
SCASSERT(paper != nullptr)
|
||||
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)
|
||||
if (paper->rect() != p->rect())
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
@ -117,7 +116,8 @@ private:
|
|||
void ObjFile(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 PrintPreview();
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "vposter.h"
|
||||
#include <QPainter>
|
||||
#include <QPrinter>
|
||||
#include <QGraphicsLineItem>
|
||||
#include <QPen>
|
||||
|
||||
#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<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)
|
||||
{
|
||||
return poster;
|
||||
}
|
||||
|
||||
const int rows = CountRows(image.rect().height());
|
||||
const int columns = CountColumns(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< columns; j++)
|
||||
{
|
||||
QImage img = Cut(i, j, image);
|
||||
img = Borders(rows, columns, 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<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
|
||||
{
|
||||
|
@ -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 y = i*PageRect().height() - i*static_cast<int>(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 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;
|
||||
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.
|
||||
}
|
||||
|
|
|
@ -29,11 +29,29 @@
|
|||
#ifndef VPOSTER_H
|
||||
#define VPOSTER_H
|
||||
|
||||
#include <QImage>
|
||||
#include <QRect>
|
||||
#include <QCoreApplication>
|
||||
|
||||
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,7 +59,9 @@ class VPoster
|
|||
public:
|
||||
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:
|
||||
const QPrinter *printer;
|
||||
quint32 allowence;
|
||||
|
@ -49,12 +69,12 @@ private:
|
|||
int CountRows(int height) 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;
|
||||
|
||||
QRect PageRect() const;
|
||||
|
||||
qreal ToPixel(qreal val) const;
|
||||
static qreal ToPixel(qreal val);
|
||||
};
|
||||
|
||||
#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));
|
||||
return printer;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "tst_vposter.h"
|
||||
#include "../vlayout/vposter.h"
|
||||
#include "../vmisc/def.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QPrinter>
|
||||
|
@ -49,15 +50,15 @@ void TST_VPoster::BigPoster()
|
|||
printer.setFullPage(true);
|
||||
// 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);
|
||||
const QVector<QImage> poster = posterazor.Generate(image, 1, 1);
|
||||
const QVector<PosterData> poster = posterazor.Calc(image, 0);
|
||||
|
||||
QCOMPARE(poster.size(), 12);
|
||||
|
||||
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.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<QImage> poster = posterazor.Generate(image, 1, 1);
|
||||
const QVector<PosterData> 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());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -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 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.
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user