2015-04-11 13:01:25 +02:00
|
|
|
/************************************************************************
|
|
|
|
**
|
|
|
|
** @file vposter.cpp
|
|
|
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
|
|
|
** @date 11 4, 2015
|
|
|
|
**
|
|
|
|
** @brief
|
|
|
|
** @copyright
|
2017-10-05 11:20:01 +02:00
|
|
|
** This source code is part of the Valentina project, a pattern making
|
2015-04-11 13:01:25 +02:00
|
|
|
** program, whose allow create and modeling patterns of clothing.
|
|
|
|
** Copyright (C) 2015 Valentina project
|
2020-01-31 07:00:05 +01:00
|
|
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
2015-04-11 13:01:25 +02:00
|
|
|
**
|
|
|
|
** Valentina is free software: you can redistribute it and/or modify
|
|
|
|
** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** Valentina is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
**
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
#include "vposter.h"
|
2016-08-08 13:44:49 +02:00
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QFont>
|
|
|
|
#include <QFontMetrics>
|
2016-06-15 12:55:43 +02:00
|
|
|
#include <QGraphicsLineItem>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QGraphicsTextItem>
|
2023-08-05 16:51:23 +02:00
|
|
|
#include <QImageReader>
|
|
|
|
#include <QPainter>
|
2016-06-15 12:55:43 +02:00
|
|
|
#include <QPen>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QPixmap>
|
2023-08-05 16:51:23 +02:00
|
|
|
#include <QPixmapCache>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QPrinter>
|
|
|
|
#include <QRectF>
|
|
|
|
#include <QString>
|
|
|
|
#include <QVector>
|
2023-08-13 09:51:38 +02:00
|
|
|
#include <QtMath>
|
2015-10-08 19:07:48 +02:00
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
#include "../ifc/exception/vexception.h"
|
|
|
|
#include "../vmisc/compatibility.h"
|
2015-06-15 13:43:41 +02:00
|
|
|
#include "../vmisc/def.h"
|
2020-10-15 17:05:21 +02:00
|
|
|
#include "../vmisc/vabstractvalapplication.h"
|
2019-12-08 13:43:26 +01:00
|
|
|
|
2023-10-07 17:56:39 +02:00
|
|
|
using namespace Qt::Literals::StringLiterals;
|
|
|
|
|
2019-12-08 13:43:26 +01:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto ToPixel(qreal val) -> qreal
|
2019-12-08 13:43:26 +01:00
|
|
|
{
|
|
|
|
return val / 25.4 * PrintDPI; // Mm to pixels with current dpi.
|
|
|
|
}
|
2019-12-13 09:51:29 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto Grayscale(QImage image) -> QImage
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
for (int ii = 0; ii < image.height(); ii++)
|
|
|
|
{
|
2023-08-05 16:51:23 +02:00
|
|
|
uchar *scan = image.scanLine(ii);
|
2019-12-13 09:51:29 +01:00
|
|
|
int depth = 4;
|
|
|
|
for (int jj = 0; jj < image.width(); jj++)
|
|
|
|
{
|
2023-08-05 16:51:23 +02:00
|
|
|
QRgb *rgbpixel = reinterpret_cast<QRgb *>(scan + jj * depth);
|
2019-12-13 09:51:29 +01:00
|
|
|
int gray = qGray(*rgbpixel);
|
|
|
|
*rgbpixel = QColor(gray, gray, gray, qAlpha(*rgbpixel)).rgba();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto WatermarkImageFromCache(const VWatermarkData &watermarkData, const QString &watermarkPath, QString &error)
|
|
|
|
-> QPixmap
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
QPixmap pixmap;
|
|
|
|
QString imagePath = AbsoluteMPath(watermarkPath, watermarkData.path);
|
|
|
|
|
2019-12-29 10:06:34 +01:00
|
|
|
if (not QPixmapCache::find(imagePath, &pixmap))
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
QImageReader imageReader(imagePath);
|
|
|
|
QImage watermark = imageReader.read();
|
|
|
|
if (watermark.isNull())
|
|
|
|
{
|
|
|
|
error = imageReader.errorString();
|
|
|
|
return pixmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (watermarkData.grayscale)
|
|
|
|
{
|
|
|
|
watermark = Grayscale(watermark);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Workaround for QGraphicsPixmapItem opacity problem.
|
|
|
|
// Opacity applied only if use a cached pixmap and only after first draw. First image always has opacity 1.
|
|
|
|
// Preparing an image manually allows to avoid the problem.
|
|
|
|
QImage tmp(watermark.width(), watermark.height(), watermark.format());
|
|
|
|
tmp = tmp.convertToFormat(QImage::Format_ARGB32);
|
|
|
|
tmp.fill(Qt::transparent);
|
|
|
|
QPainter p;
|
|
|
|
p.begin(&tmp);
|
2023-08-05 16:51:23 +02:00
|
|
|
p.setOpacity(watermarkData.opacity / 100.);
|
2019-12-13 09:51:29 +01:00
|
|
|
p.drawImage(QPointF(), watermark);
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
pixmap = QPixmap::fromImage(tmp);
|
|
|
|
|
|
|
|
QPixmapCache::insert(imagePath, pixmap);
|
|
|
|
}
|
|
|
|
return pixmap;
|
|
|
|
}
|
2023-08-05 16:51:23 +02:00
|
|
|
} // namespace
|
2015-04-11 13:01:25 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VPoster::VPoster(const QPrinter *printer)
|
2023-08-05 16:51:23 +02:00
|
|
|
: printer(printer),
|
|
|
|
allowance(static_cast<quint32>(qRound(CmToPixel(1.))))
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::Calc(const QSize &imageRect, int page, PageOrientation orientation) const -> QVector<PosterData>
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
2016-06-15 12:55:43 +02:00
|
|
|
QVector<PosterData> poster;
|
2015-04-11 13:01:25 +02:00
|
|
|
|
|
|
|
if (printer == nullptr)
|
|
|
|
{
|
|
|
|
return poster;
|
|
|
|
}
|
|
|
|
|
2017-10-10 11:22:59 +02:00
|
|
|
const int rows = CountRows(imageRect.height(), orientation);
|
|
|
|
const int columns = CountColumns(imageRect.width(), orientation);
|
2015-04-11 13:01:25 +02:00
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
for (int i = 0; i < rows; i++)
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
2023-08-05 16:51:23 +02:00
|
|
|
for (int j = 0; j < columns; j++)
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
2017-10-10 11:22:59 +02:00
|
|
|
PosterData data = Cut(i, j, imageRect, orientation);
|
2016-11-01 09:42:32 +01:00
|
|
|
data.index = static_cast<quint32>(page);
|
|
|
|
data.rows = static_cast<quint32>(rows);
|
|
|
|
data.columns = static_cast<quint32>(columns);
|
2016-06-15 12:55:43 +02:00
|
|
|
poster.append(data);
|
2015-04-11 13:01:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return poster;
|
|
|
|
}
|
|
|
|
|
2019-12-13 09:51:29 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::Tile(QGraphicsItem *parent, const PosterData &img, vsizetype sheets, const VWatermarkData &watermarkData,
|
|
|
|
const QString &watermarkPath) const -> QVector<QGraphicsItem *>
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
QVector<QGraphicsItem *> data;
|
|
|
|
data.append(Borders(parent, img, sheets));
|
|
|
|
|
|
|
|
if (watermarkData.opacity > 0)
|
|
|
|
{
|
2019-12-30 13:43:06 +01:00
|
|
|
if (watermarkData.showImage && not watermarkData.path.isEmpty())
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
data += ImageWatermark(parent, img, watermarkData, watermarkPath);
|
|
|
|
}
|
|
|
|
|
2019-12-30 13:43:06 +01:00
|
|
|
if (watermarkData.showText && not watermarkData.text.isEmpty())
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
data += TextWatermark(parent, img, watermarkData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2016-06-15 12:55:43 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::Borders(QGraphicsItem *parent, const PosterData &img, vsizetype sheets) const -> QVector<QGraphicsItem *>
|
2016-06-15 12:55:43 +02:00
|
|
|
{
|
2019-08-05 09:21:04 +02:00
|
|
|
SCASSERT(parent != nullptr)
|
|
|
|
|
2016-06-15 12:55:43 +02:00
|
|
|
QVector<QGraphicsItem *> data;
|
|
|
|
QPen pen(Qt::NoBrush, 1, Qt::DashLine);
|
|
|
|
pen.setColor(Qt::black);
|
|
|
|
|
2017-10-11 10:34:22 +02:00
|
|
|
if (img.columns == 1 && img.rows == 1)
|
|
|
|
{
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2016-06-15 12:55:43 +02:00
|
|
|
const QRect rec = img.rect;
|
|
|
|
if (img.column != 0)
|
2023-08-05 16:51:23 +02:00
|
|
|
{ // Left border
|
2016-06-15 12:55:43 +02:00
|
|
|
auto *line = new QGraphicsLineItem(parent);
|
|
|
|
line->setPen(pen);
|
|
|
|
line->setLine(rec.x(), rec.y(), rec.x(), rec.y() + rec.height());
|
|
|
|
data.append(line);
|
|
|
|
|
2019-08-05 09:21:04 +02:00
|
|
|
auto *scissors = new QGraphicsPixmapItem(QPixmap(QStringLiteral("://scissors_vertical.png")), parent);
|
2023-08-05 16:51:23 +02:00
|
|
|
scissors->setPos(rec.x(), rec.y() + rec.height() - static_cast<int>(allowance));
|
2016-06-15 12:55:43 +02:00
|
|
|
data.append(scissors);
|
|
|
|
}
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
if (img.column != img.columns - 1)
|
|
|
|
{ // Right border
|
2016-06-15 12:55:43 +02:00
|
|
|
auto *line = new QGraphicsLineItem(parent);
|
|
|
|
line->setPen(pen);
|
2023-08-05 16:51:23 +02:00
|
|
|
line->setLine(rec.x() + rec.width() - static_cast<int>(allowance), rec.y(),
|
|
|
|
rec.x() + rec.width() - static_cast<int>(allowance), rec.y() + rec.height());
|
2016-06-15 12:55:43 +02:00
|
|
|
data.append(line);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (img.row != 0)
|
2023-08-05 16:51:23 +02:00
|
|
|
{ // Top border
|
2016-06-15 12:55:43 +02:00
|
|
|
auto *line = new QGraphicsLineItem(parent);
|
|
|
|
line->setPen(pen);
|
|
|
|
line->setLine(rec.x(), rec.y(), rec.x() + rec.width(), rec.y());
|
|
|
|
data.append(line);
|
|
|
|
|
2019-08-05 09:21:04 +02:00
|
|
|
auto *scissors = new QGraphicsPixmapItem(QPixmap(QStringLiteral("://scissors_horizontal.png")), parent);
|
2023-08-05 16:51:23 +02:00
|
|
|
scissors->setPos(rec.x() + rec.width() - static_cast<int>(allowance), rec.y());
|
2016-06-15 12:55:43 +02:00
|
|
|
data.append(scissors);
|
|
|
|
}
|
|
|
|
|
2019-08-05 09:21:04 +02:00
|
|
|
// Bottom border (mandatory)
|
|
|
|
auto *line = new QGraphicsLineItem(parent);
|
|
|
|
line->setPen(pen);
|
2023-08-05 16:51:23 +02:00
|
|
|
line->setLine(rec.x(), rec.y() + rec.height() - static_cast<int>(allowance), rec.x() + rec.width(),
|
|
|
|
rec.y() + rec.height() - static_cast<int>(allowance));
|
2019-08-05 09:21:04 +02:00
|
|
|
data.append(line);
|
2016-06-15 12:55:43 +02:00
|
|
|
|
2019-12-08 13:43:26 +01:00
|
|
|
// Ruler
|
|
|
|
Ruler(data, parent, rec);
|
2019-12-07 22:18:44 +01:00
|
|
|
|
2016-06-15 12:55:43 +02:00
|
|
|
// Labels
|
|
|
|
auto *labels = new QGraphicsTextItem(parent);
|
|
|
|
|
|
|
|
const int layoutX = 15;
|
|
|
|
const int layoutY = 5;
|
2023-08-05 16:51:23 +02:00
|
|
|
labels->setPos(rec.x() + layoutX, rec.y() + rec.height() - static_cast<int>(allowance) + layoutY);
|
|
|
|
labels->setTextWidth(rec.width() - (static_cast<int>(allowance) + layoutX));
|
2016-06-15 12:55:43 +02:00
|
|
|
|
2023-05-08 16:50:58 +02:00
|
|
|
const QString grid =
|
|
|
|
QCoreApplication::translate("VPoster", "Grid ( %1 , %2 )").arg(img.row + 1).arg(img.column + 1);
|
|
|
|
const QString page = QCoreApplication::translate("VPoster", "Page %1 of %2")
|
|
|
|
.arg(img.row * (img.columns) + img.column + 1)
|
|
|
|
.arg(img.rows * img.columns);
|
2016-06-15 12:55:43 +02:00
|
|
|
|
|
|
|
QString sheet;
|
|
|
|
if (sheets > 1)
|
|
|
|
{
|
2023-05-08 16:50:58 +02:00
|
|
|
sheet = QCoreApplication::translate("VPoster", "Sheet %1 of %2").arg(img.index + 1).arg(sheets);
|
2016-06-15 12:55:43 +02:00
|
|
|
}
|
|
|
|
|
2023-10-07 17:56:39 +02:00
|
|
|
labels->setHtml(u"<table width='100%'>"
|
2023-10-09 11:45:34 +02:00
|
|
|
u"<tr>"
|
|
|
|
u"<td>%1</td><td align='center'>%2</td><td align='right'>%3</td>"
|
|
|
|
u"</tr>"
|
|
|
|
u"</table>"_s.arg(grid, page, sheet));
|
2016-06-15 12:55:43 +02:00
|
|
|
|
|
|
|
data.append(labels);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2019-12-13 09:51:29 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::TextWatermark(QGraphicsItem *parent, const PosterData &img, const VWatermarkData &watermarkData) const
|
|
|
|
-> QVector<QGraphicsItem *>
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
SCASSERT(parent != nullptr)
|
|
|
|
|
|
|
|
QVector<QGraphicsItem *> data;
|
|
|
|
|
|
|
|
QGraphicsSimpleTextItem *text = new QGraphicsSimpleTextItem(watermarkData.text, parent);
|
|
|
|
text->setFont(watermarkData.font);
|
2021-09-11 18:39:38 +02:00
|
|
|
|
|
|
|
QPen pen = text->pen();
|
|
|
|
pen.setColor(watermarkData.textColor);
|
|
|
|
text->setPen(pen);
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
text->setOpacity(watermarkData.opacity / 100.);
|
2019-12-13 09:51:29 +01:00
|
|
|
text->setTransformOriginPoint(text->boundingRect().center());
|
|
|
|
text->setRotation(-watermarkData.textRotation);
|
|
|
|
|
|
|
|
const QRect boundingRect = text->boundingRect().toRect();
|
|
|
|
int x = img.rect.x() + (img.rect.width() - boundingRect.width()) / 2;
|
|
|
|
int y = img.rect.y() + (img.rect.height() - boundingRect.height()) / 2;
|
|
|
|
|
|
|
|
text->setX(x);
|
|
|
|
text->setY(y);
|
|
|
|
text->setZValue(-1);
|
|
|
|
|
|
|
|
data.append(text);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::ImageWatermark(QGraphicsItem *parent, const PosterData &img, const VWatermarkData &watermarkData,
|
|
|
|
const QString &watermarkPath) const -> QVector<QGraphicsItem *>
|
2019-12-13 09:51:29 +01:00
|
|
|
{
|
|
|
|
SCASSERT(parent != nullptr)
|
|
|
|
|
|
|
|
QVector<QGraphicsItem *> data;
|
|
|
|
|
|
|
|
QGraphicsItem *image = nullptr;
|
|
|
|
|
|
|
|
QFileInfo f(watermarkData.path);
|
|
|
|
if (f.suffix() == "png" || f.suffix() == "jpg" || f.suffix() == "jpeg" || f.suffix() == "bmp")
|
|
|
|
{
|
|
|
|
QString error;
|
|
|
|
QPixmap watermark = WatermarkImageFromCache(watermarkData, watermarkPath, error);
|
|
|
|
|
|
|
|
if (watermark.isNull())
|
|
|
|
{
|
2023-05-08 16:50:58 +02:00
|
|
|
const QString errorMsg =
|
2023-10-07 17:56:39 +02:00
|
|
|
QCoreApplication::translate("VPoster", "Cannot open the watermark image.") + ' '_L1 + error;
|
2023-08-05 16:51:23 +02:00
|
|
|
VAbstractApplication::VApp()->IsPedantic()
|
|
|
|
? throw VException(errorMsg)
|
|
|
|
: qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
2019-12-13 09:51:29 +01:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
image = new QGraphicsPixmapItem(watermark, parent);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-05-08 16:50:58 +02:00
|
|
|
const QString errorMsg =
|
|
|
|
QCoreApplication::translate("VPoster", "Not supported file suffix '%1'").arg(f.suffix());
|
2023-08-05 16:51:23 +02:00
|
|
|
VAbstractApplication::VApp()->IsPedantic()
|
|
|
|
? throw VException(errorMsg)
|
|
|
|
: qWarning() << VAbstractValApplication::warningMessageSignature + errorMsg;
|
2019-12-13 09:51:29 +01:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
image->setZValue(-1);
|
|
|
|
image->setTransformOriginPoint(image->boundingRect().center());
|
|
|
|
image->setRotation(-watermarkData.imageRotation);
|
|
|
|
|
|
|
|
const QRect boundingRect = image->boundingRect().toRect();
|
|
|
|
int x = img.rect.x() + (img.rect.width() - boundingRect.width()) / 2;
|
|
|
|
int y = img.rect.y() + (img.rect.height() - boundingRect.height()) / 2;
|
|
|
|
|
|
|
|
image->setX(x);
|
|
|
|
image->setY(y);
|
|
|
|
|
|
|
|
data.append(image);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2015-04-11 13:01:25 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::CountRows(int height, PageOrientation orientation) const -> int
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
|
|
|
const qreal imgLength = height;
|
2017-10-10 11:22:59 +02:00
|
|
|
qreal pageLength = 0;
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
if (orientation == PageOrientation::Landscape)
|
2017-10-10 11:22:59 +02:00
|
|
|
{
|
|
|
|
pageLength = PageRect().width();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pageLength = PageRect().height();
|
|
|
|
}
|
|
|
|
|
2017-10-11 10:34:22 +02:00
|
|
|
if (pageLength >= imgLength)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2023-08-13 09:51:54 +02:00
|
|
|
|
|
|
|
return qCeil(imgLength / (pageLength - static_cast<int>(allowance)));
|
2015-04-11 13:01:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::CountColumns(int width, PageOrientation orientation) const -> int
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
|
|
|
const qreal imgLength = width;
|
2017-10-10 11:22:59 +02:00
|
|
|
qreal pageLength = 0;
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
if (orientation == PageOrientation::Landscape)
|
2017-10-10 11:22:59 +02:00
|
|
|
{
|
|
|
|
pageLength = PageRect().height();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pageLength = PageRect().width();
|
|
|
|
}
|
|
|
|
|
2017-10-11 10:34:22 +02:00
|
|
|
if (pageLength >= imgLength)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
2023-08-13 09:51:54 +02:00
|
|
|
|
|
|
|
return qCeil(imgLength / (pageLength - static_cast<int>(allowance)));
|
2015-04-11 13:01:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::Cut(int i, int j, const QSize &imageRect, PageOrientation orientation) const -> PosterData
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
2016-12-20 20:19:21 +01:00
|
|
|
Q_UNUSED(imageRect)
|
2016-07-06 20:49:36 +02:00
|
|
|
|
2017-10-10 11:22:59 +02:00
|
|
|
int pageLengthX, pageLengthY;
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
if (orientation == PageOrientation::Landscape)
|
2017-10-10 11:22:59 +02:00
|
|
|
{
|
|
|
|
pageLengthX = PageRect().height();
|
|
|
|
pageLengthY = PageRect().width();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pageLengthX = PageRect().width();
|
|
|
|
pageLengthY = PageRect().height();
|
|
|
|
}
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
const int x = j * pageLengthX - j * static_cast<int>(allowance);
|
|
|
|
const int y = i * pageLengthY - i * static_cast<int>(allowance);
|
2015-04-11 13:01:25 +02:00
|
|
|
|
2016-12-20 19:57:20 +01:00
|
|
|
SCASSERT(x <= imageRect.width())
|
|
|
|
SCASSERT(y <= imageRect.height())
|
2015-04-11 13:01:25 +02:00
|
|
|
|
2016-06-15 12:55:43 +02:00
|
|
|
PosterData data;
|
2016-11-01 09:42:32 +01:00
|
|
|
data.row = static_cast<quint32>(i);
|
|
|
|
data.column = static_cast<quint32>(j);
|
2017-10-10 11:22:59 +02:00
|
|
|
data.rect = QRect(x, y, pageLengthX, pageLengthY);
|
2015-04-11 13:01:25 +02:00
|
|
|
|
2016-06-15 12:55:43 +02:00
|
|
|
return data;
|
2015-04-11 13:01:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2023-05-03 13:07:02 +02:00
|
|
|
auto VPoster::PageRect() const -> QRect
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
2015-04-15 11:10:35 +02:00
|
|
|
// Because the Point unit is defined to be 1/72th of an inch
|
2015-11-09 12:33:36 +01:00
|
|
|
// we can't use method pageRect(QPrinter::Point). Our dpi value can be different.
|
2015-04-15 11:10:35 +02:00
|
|
|
// We convert value yourself to pixels.
|
2015-04-11 13:01:25 +02:00
|
|
|
const QRectF rect = printer->pageRect(QPrinter::Millimeter);
|
2016-10-23 11:11:00 +02:00
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
if (printer->fullPage())
|
2016-10-23 11:11:00 +02:00
|
|
|
{
|
2020-03-20 09:19:31 +01:00
|
|
|
QPageLayout layout = printer->pageLayout();
|
|
|
|
layout.setUnits(QPageLayout::Millimeter);
|
|
|
|
QMarginsF pMargins = layout.margins();
|
2019-04-05 14:42:22 +02:00
|
|
|
QRectF newRect = rect.marginsRemoved(pMargins);
|
|
|
|
const QRect pageRectFP(0, 0, qFloor(ToPixel(newRect.width())), qFloor(ToPixel(newRect.height())));
|
|
|
|
return pageRectFP;
|
2016-10-23 11:11:00 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const QRect pageRect(0, 0, qFloor(ToPixel(rect.width())), qFloor(ToPixel(rect.height())));
|
|
|
|
return pageRect;
|
|
|
|
}
|
2015-04-11 13:01:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2019-12-08 13:43:26 +01:00
|
|
|
void VPoster::Ruler(QVector<QGraphicsItem *> &data, QGraphicsItem *parent, QRect rec) const
|
2015-04-11 13:01:25 +02:00
|
|
|
{
|
2019-12-08 13:43:26 +01:00
|
|
|
SCASSERT(parent != nullptr)
|
|
|
|
|
|
|
|
QPen rulePen(Qt::NoBrush, 1, Qt::SolidLine);
|
|
|
|
rulePen.setColor(Qt::black);
|
|
|
|
|
2023-08-05 16:51:23 +02:00
|
|
|
const qreal notchHeight = ToPixel(3); // mm
|
2019-12-08 13:43:26 +01:00
|
|
|
const qreal shortNotchHeight = ToPixel(1.1); // mm
|
2021-02-06 14:52:21 +01:00
|
|
|
Unit patternUnits = VAbstractValApplication::VApp()->patternUnits();
|
2019-12-08 13:43:26 +01:00
|
|
|
const qreal step = UnitConvertor(1, patternUnits, Unit::Px);
|
|
|
|
double marksCount = rec.width() / step;
|
|
|
|
int i = 0;
|
|
|
|
while (i < marksCount)
|
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
{ // don't need 0 notch
|
|
|
|
auto *middleRuleLine = new QGraphicsLineItem(parent);
|
|
|
|
middleRuleLine->setPen(rulePen);
|
|
|
|
middleRuleLine->setLine(rec.x() + step * i - step / 2.,
|
2023-08-05 16:51:23 +02:00
|
|
|
rec.y() + rec.height() - static_cast<int>(allowance),
|
|
|
|
rec.x() + step * i - step / 2.,
|
|
|
|
rec.y() + rec.height() - static_cast<int>(allowance) + shortNotchHeight);
|
2019-12-08 13:43:26 +01:00
|
|
|
data.append(middleRuleLine);
|
|
|
|
|
|
|
|
auto *ruleLine = new QGraphicsLineItem(parent);
|
|
|
|
ruleLine->setPen(rulePen);
|
2023-08-05 16:51:23 +02:00
|
|
|
ruleLine->setLine(rec.x() + step * i, rec.y() + rec.height() - static_cast<int>(allowance),
|
|
|
|
rec.x() + step * i, rec.y() + rec.height() - static_cast<int>(allowance) + notchHeight);
|
2019-12-08 13:43:26 +01:00
|
|
|
data.append(ruleLine);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto *units = new QGraphicsTextItem(parent);
|
2023-08-05 16:51:23 +02:00
|
|
|
units->setPlainText(patternUnits == Unit::Cm || patternUnits == Unit::Mm ? tr("cm", "unit")
|
|
|
|
: tr("in", "unit"));
|
2019-12-08 13:43:26 +01:00
|
|
|
QFont fnt = units->font();
|
|
|
|
fnt.setPointSize(10);
|
|
|
|
|
|
|
|
qreal unitsWidth = 0;
|
|
|
|
QFontMetrics fm(fnt);
|
2022-02-19 20:26:30 +01:00
|
|
|
unitsWidth = TextWidth(fm, units->toPlainText());
|
2023-08-05 16:51:23 +02:00
|
|
|
units->setPos(rec.x() + step * 0.5 - unitsWidth * 0.7,
|
|
|
|
rec.y() + rec.height() - static_cast<int>(allowance) - shortNotchHeight);
|
2019-12-08 13:43:26 +01:00
|
|
|
units->setFont(fnt);
|
|
|
|
data.append(units);
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
2015-04-11 13:01:25 +02:00
|
|
|
}
|