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:
Roman Telezhynskyi 2016-06-15 13:55:43 +03:00
parent 00f854f1d9
commit 972dd36fcf
9 changed files with 280 additions and 246 deletions

View file

@ -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);

View file

@ -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>

View file

@ -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,62 +774,31 @@ 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)
auto *paper = qgraphicsitem_cast<QGraphicsRectItem *>(papers.at(index));
if (paper)
{
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(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 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);
// 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::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<QGraphicsRectItem *>(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;
}
//---------------------------------------------------------------------------------------------------------------------
@ -855,7 +860,7 @@ void MainWindowsNoGUI::PrintPreview()
SetPrinterSettings(printer.data(), PrintType::PrintPreview);
printer->setResolution(static_cast<int>(PrintDPI));
// display print preview dialog
QPrintPreviewDialog preview(printer.data());
QPrintPreviewDialog preview(printer.data());
connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindowsNoGUI::PrintPages);
preview.exec();
}
@ -897,21 +902,16 @@ void MainWindowsNoGUI::SetPrinterSettings(QPrinter *printer, const PrintType &pr
printer->setCreator(qApp->applicationDisplayName()+" "+qApp->applicationVersion());
// Set orientation
if (papers.size() > 0)
if (paperSize.height() >= paperSize.width())
{
QGraphicsRectItem *paper = qgraphicsitem_cast<QGraphicsRectItem *>(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);
@ -968,13 +968,33 @@ 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)
{
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
{
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())
{

View file

@ -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();

View file

@ -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.
}

View file

@ -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

View file

@ -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;
}

View file

@ -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.
}

View file

@ -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;
};