Minor bufixes in axial shading, clipping on crop box

This commit is contained in:
Jakub Melka 2019-09-01 15:44:22 +02:00
parent 3e345a768f
commit 69ba66ae04
7 changed files with 60 additions and 15 deletions

View File

@ -1229,7 +1229,7 @@ PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* d
if (characterContentStreamObject.isStream())
{
QByteArray contentStream = document->getDecodedStream(characterContentStreamObject.getStream());
characterContentStreams[currentOffset] = qMove(contentStream);
characterContentStreams[static_cast<int>(currentOffset)] = qMove(contentStream);
}
++currentOffset;

View File

@ -121,6 +121,11 @@ QRectF PDFPage::getRotatedMediaBox() const
return getRotatedBox(getMediaBox(), getPageRotation());
}
QRectF PDFPage::getRotatedCropBox() const
{
return getRotatedBox(getCropBox(), getPageRotation());
}
QRectF PDFPage::getRotatedBox(const QRectF& rect, PageRotation rotation)
{
switch (rotation)

View File

@ -95,6 +95,7 @@ public:
inline QRectF getArtBoxMM() const { return getRectMM(m_artBox); }
QRectF getRotatedMediaBox() const;
QRectF getRotatedCropBox() const;
static QRectF getRotatedBox(const QRectF& rect, PageRotation rotation);

View File

@ -38,6 +38,18 @@ PDFPainter::PDFPainter(QPainter* painter,
Q_ASSERT(pagePointToDevicePointMatrix.isInvertible());
m_painter->save();
if (features.testFlag(PDFRenderer::ClipToCropBox))
{
QRectF cropBox = page->getRotatedCropBox();
if (cropBox.isValid())
{
QPainterPath path;
path.addPolygon(pagePointToDevicePointMatrix.map(cropBox));
m_painter->setClipPath(path, Qt::IntersectClip);
}
}
}
PDFPainter::~PDFPainter()

View File

@ -239,6 +239,12 @@ PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) cons
xCoords.push_back(x);
}
}
if (xCoords.back() + PDF_EPSILON < p2m.x())
{
xCoords.push_back(p2m.x());
}
if (!qFuzzyCompare(xCoords.back(), xr))
{
xCoords.push_back(xr);
@ -319,18 +325,21 @@ PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) cons
const std::pair<PDFReal, PDFColor>& currentItem = *it;
const std::pair<PDFReal, PDFColor>& nextItem = *itNext;
if (prevItem.second == currentItem.second && currentItem.second == nextItem.second)
if (currentItem.first != p1m.x() && currentItem.first != p2m.x())
{
// Colors are same, skip the test
continue;
}
if (prevItem.second == currentItem.second && currentItem.second == nextItem.second)
{
// Colors are same, skip the test
continue;
}
if (PDFAbstractColorSpace::isColorEqual(prevItem.second, currentItem.second, settings.tolerance) &&
PDFAbstractColorSpace::isColorEqual(currentItem.second, nextItem.second, settings.tolerance) &&
PDFAbstractColorSpace::isColorEqual(prevItem.second, nextItem.second, settings.tolerance) &&
(nextItem.first - prevItem.first < settings.preferredMeshResolution))
{
continue;
if (PDFAbstractColorSpace::isColorEqual(prevItem.second, currentItem.second, settings.tolerance) &&
PDFAbstractColorSpace::isColorEqual(currentItem.second, nextItem.second, settings.tolerance) &&
PDFAbstractColorSpace::isColorEqual(prevItem.second, nextItem.second, settings.tolerance) &&
(nextItem.first - prevItem.first < settings.preferredMeshResolution))
{
continue;
}
}
}
@ -370,7 +379,26 @@ PDFMesh PDFAxialShading::createMesh(const PDFMeshQualitySettings& settings) cons
}
// Create background color triangles
// TODO: Create background color for axial shading
if (m_backgroundColor.isValid() && (!m_extendStart || !m_extendEnd))
{
if (!m_extendStart && xl + PDF_EPSILON < p1m.x())
{
uint32_t topLeft = mesh.addVertex(QPointF(xl, yt));
uint32_t topRight = mesh.addVertex(QPointF(p1m.x(), yt));
uint32_t bottomLeft = mesh.addVertex(QPointF(xl, yb));
uint32_t bottomRight = mesh.addVertex(QPointF(p1m.x(), yb));
mesh.addQuad(topLeft, topRight, bottomRight, bottomLeft, m_backgroundColor.rgb());
}
if (!m_extendEnd && p2m.x() + PDF_EPSILON < xr)
{
uint32_t topRight = mesh.addVertex(QPointF(xr, yt));
uint32_t topLeft = mesh.addVertex(QPointF(p2m.x(), yt));
uint32_t bottomRight = mesh.addVertex(QPointF(xr, yb));
uint32_t bottomLeft = mesh.addVertex(QPointF(p2m.x(), yb));
mesh.addQuad(topLeft, topRight, bottomRight, bottomLeft, m_backgroundColor.rgb());
}
}
// Transform mesh to the device space coordinates
mesh.transform(p1p2LCS);

View File

@ -31,8 +31,6 @@ PDFRenderer::PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCa
Q_ASSERT(document);
}
// TODO: Clipovani na stranku
QList<PDFRenderError> PDFRenderer::render(QPainter* painter, const QRectF& rectangle, size_t pageIndex) const
{
Q_UNUSED(painter);

View File

@ -39,6 +39,7 @@ public:
TextAntialiasing = 0x0002, ///< Antialiasing for drawing text
SmoothImages = 0x0004, ///< Adjust images to the device space using smooth transformation (slower, but better image quality)
IgnoreOptionalContent = 0x0008, ///< Ignore optional content (so all is drawn ignoring settings of optional content)
ClipToCropBox = 0x0010, ///< Clip page content to crop box (items outside crop box will not be visible)
};
Q_DECLARE_FLAGS(Features, Feature)
@ -59,7 +60,7 @@ public:
QList<PDFRenderError> render(QPainter* painter, const QMatrix& matrix, size_t pageIndex) const;
/// Returns default renderer features
static constexpr Features getDefaultFeatures() { return Antialiasing | TextAntialiasing; }
static constexpr Features getDefaultFeatures() { return Antialiasing | TextAntialiasing | ClipToCropBox; }
private:
const PDFDocument* m_document;