File indexing completed on 2024-05-05 04:05:48
0001 /* 0002 SPDX-FileCopyrightText: 2009 Stefan Majewsky <majewsky@gmx.net> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "slicerjob.h" 0008 #include "slicer.h" 0009 0010 #include <QPainter> 0011 0012 //BEGIN Pala::SlicerJobPrivate 0013 0014 class Pala::SlicerJobPrivate 0015 { 0016 public: 0017 SlicerJobPrivate() : m_mode(nullptr) {} 0018 0019 QMap<QByteArray, QVariant> m_args; 0020 QImage m_image; 0021 const Pala::SlicerMode* m_mode; 0022 0023 QMap<int, QImage> m_pieces; 0024 QMap<int, QPoint> m_pieceOffsets; 0025 QList<QPair<int, int> > m_relations; 0026 }; 0027 0028 //END Pala::SlicerJobPrivate 0029 0030 Pala::SlicerJob::SlicerJob(const QImage& image, const QMap<QByteArray, QVariant>& args) 0031 : d_ptr(new SlicerJobPrivate) 0032 { 0033 Q_D(SlicerJob); 0034 d->m_args = args; 0035 d->m_image = image; 0036 } 0037 0038 Pala::SlicerJob::~SlicerJob() = default; 0039 0040 QVariant Pala::SlicerJob::argument(const QByteArray& key) const 0041 { 0042 Q_D(const SlicerJob); 0043 return d->m_args.value(key, QVariant()); 0044 } 0045 0046 QImage Pala::SlicerJob::image() const 0047 { 0048 Q_D(const SlicerJob); 0049 return d->m_image; 0050 } 0051 0052 const Pala::SlicerMode* Pala::SlicerJob::mode() const 0053 { 0054 Q_D(const SlicerJob); 0055 return d->m_mode; 0056 } 0057 0058 QMap<int, QImage> Pala::SlicerJob::pieces() const 0059 { 0060 Q_D(const SlicerJob); 0061 return d->m_pieces; 0062 } 0063 0064 QMap<int, QPoint> Pala::SlicerJob::pieceOffsets() const 0065 { 0066 Q_D(const SlicerJob); 0067 return d->m_pieceOffsets; 0068 } 0069 0070 QList<QPair<int, int> > Pala::SlicerJob::relations() const 0071 { 0072 Q_D(const SlicerJob); 0073 return d->m_relations; 0074 } 0075 0076 void Pala::SlicerJob::setMode(const Pala::SlicerMode* mode) 0077 { 0078 Q_D(SlicerJob); 0079 d->m_mode = mode; 0080 } 0081 0082 void Pala::SlicerJob::respectSlicerFlags(int flags) 0083 { 0084 Q_D(SlicerJob); 0085 if (!(flags & Pala::Slicer::AllowFullTransparency)) 0086 { 0087 QImage image(d->m_image.size(), d->m_image.format()); 0088 QColor blackShade(Qt::black); blackShade.setAlpha(42); 0089 image.fill(blackShade.rgba()); 0090 QPainter painter(&image); 0091 painter.drawImage(QPoint(), d->m_image); 0092 painter.end(); 0093 d->m_image = image; 0094 } 0095 } 0096 0097 void Pala::SlicerJob::addPiece(int pieceID, const QImage& image, const QPoint& offset) 0098 { 0099 Q_D(SlicerJob); 0100 d->m_pieces.insert(pieceID, image); 0101 d->m_pieceOffsets.insert(pieceID, offset); 0102 } 0103 0104 //A modified version of QImage::copy, which avoids rendering errors even if rect is outside the bounds of the source image. 0105 static 0106 QImage safeQImageCopy(const QImage& source, const QRect& rect) 0107 { 0108 QRect targetRect(QPoint(), rect.size()); 0109 //copy image 0110 QImage target(rect.size(), source.format()); 0111 QPainter p(&target); 0112 p.drawImage(targetRect, source, rect); 0113 p.end(); 0114 return target; 0115 //Strangely, source.copy(rect) does not work. It produces black borders. 0116 } 0117 0118 void Pala::SlicerJob::addPieceFromMask(int pieceID, const QImage& mask, const QPoint& offset) 0119 { 0120 Q_D(SlicerJob); 0121 QImage pieceImage(mask); 0122 QPainter painter(&pieceImage); 0123 painter.setCompositionMode(QPainter::CompositionMode_SourceIn); 0124 painter.drawImage(QPoint(), safeQImageCopy(d->m_image, QRect(offset, mask.size()))); 0125 painter.end(); 0126 addPiece(pieceID, pieceImage, offset); 0127 } 0128 0129 void Pala::SlicerJob::addRelation(int pieceID1, int pieceID2) 0130 { 0131 Q_D(SlicerJob); 0132 d->m_relations << QPair<int, int>(pieceID1, pieceID2); 0133 }