mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-18 04:10:23 +01:00
Minor bugfixes
This commit is contained in:
parent
3ad7485dbf
commit
0447b9e3a1
@ -408,7 +408,7 @@ void PDFDrawWidgetProxy::update()
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentBlock = qBound<PDFInteger>(0, m_currentBlock, m_controller->getBlockCount());
|
||||
m_currentBlock = qBound<PDFInteger>(0, m_currentBlock, m_controller->getBlockCount() - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -579,6 +579,26 @@ std::vector<PDFInteger> PDFDrawWidgetProxy::getPagesIntersectingRect(QRect rect)
|
||||
return pages;
|
||||
}
|
||||
|
||||
QRect PDFDrawWidgetProxy::getPagesIntersectingRectBoundingBox(QRect rect) const
|
||||
{
|
||||
QRect resultRect;
|
||||
|
||||
// Iterate trough pages, place them and test, if they intersects with rectangle
|
||||
for (const LayoutItem& item : m_layout.items)
|
||||
{
|
||||
// The offsets m_horizontalOffset and m_verticalOffset are offsets to the
|
||||
// topleft point of the block. But block maybe doesn't start at (0, 0),
|
||||
// so we must also use translation from the block beginning.
|
||||
QRect placedRect = item.pageRect.translated(m_horizontalOffset - m_layout.blockRect.left(), m_verticalOffset - m_layout.blockRect.top());
|
||||
if (placedRect.intersects(rect))
|
||||
{
|
||||
resultRect = resultRect.united(placedRect);
|
||||
}
|
||||
}
|
||||
|
||||
return resultRect;
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::performOperation(Operation operation)
|
||||
{
|
||||
switch (operation)
|
||||
@ -645,10 +665,15 @@ void PDFDrawWidgetProxy::performOperation(Operation operation)
|
||||
}
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::scrollByPixels(QPoint offset)
|
||||
QPoint PDFDrawWidgetProxy::scrollByPixels(QPoint offset)
|
||||
{
|
||||
PDFInteger oldHorizontalOffset = m_horizontalOffset;
|
||||
PDFInteger oldVerticalOffset = m_verticalOffset;
|
||||
|
||||
setHorizontalOffset(m_horizontalOffset + offset.x());
|
||||
setVerticalOffset(m_verticalOffset + offset.y());
|
||||
|
||||
return QPoint(m_horizontalOffset - oldHorizontalOffset, m_verticalOffset - oldVerticalOffset);
|
||||
}
|
||||
|
||||
void PDFDrawWidgetProxy::zoom(PDFReal zoom)
|
||||
|
@ -170,9 +170,9 @@ public:
|
||||
void performOperation(Operation operation);
|
||||
|
||||
/// Scrolls by pixels, if it is possible. If it is not possible to scroll,
|
||||
/// then nothing happens.
|
||||
/// then nothing happens. Returns pixel offset, by which view camera was moved.
|
||||
/// \param offset Offset in pixels
|
||||
void scrollByPixels(QPoint offset);
|
||||
QPoint scrollByPixels(QPoint offset);
|
||||
|
||||
/// Sets the zoom. Tries to preserve current offsets (so the current visible
|
||||
/// area will be visible after the zoom).
|
||||
@ -194,6 +194,14 @@ public:
|
||||
/// \param rect Rectangle to test
|
||||
std::vector<PDFInteger> getPagesIntersectingRect(QRect rect) const;
|
||||
|
||||
/// Returns bounding box of pages, which are intersecting rectangle (even partially)
|
||||
/// \param rect Rectangle to test
|
||||
QRect getPagesIntersectingRectBoundingBox(QRect rect) const;
|
||||
|
||||
/// Returns true, if we are in the block mode (multiple blocks with separate pages),
|
||||
/// or continuous mode (single block with continuous list of separated pages).
|
||||
bool isBlockMode() const;
|
||||
|
||||
static constexpr PDFReal ZOOM_STEP = 1.2;
|
||||
|
||||
signals:
|
||||
@ -237,10 +245,6 @@ private:
|
||||
/// Converts rectangle from device space to the pixel space
|
||||
QRectF fromDeviceSpace(const QRectF& rect) const;
|
||||
|
||||
/// Returns true, if we are in the block mode (multiple blocks with separate pages),
|
||||
/// or continuous mode (single block with continuous list of separated pages).
|
||||
bool isBlockMode() const;
|
||||
|
||||
void onHorizontalScrollbarValueChanged(int value);
|
||||
void onVerticalScrollbarValueChanged(int value);
|
||||
|
||||
|
@ -193,6 +193,7 @@ void PDFDrawWidget::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
Qt::KeyboardModifiers keyboardModifiers = QApplication::keyboardModifiers();
|
||||
|
||||
PDFDrawWidgetProxy* proxy = m_widget->getDrawWidgetProxy();
|
||||
if (keyboardModifiers.testFlag(Qt::ControlModifier))
|
||||
{
|
||||
// Zoom in/Zoom out
|
||||
@ -200,7 +201,7 @@ void PDFDrawWidget::wheelEvent(QWheelEvent* event)
|
||||
const PDFReal zoom = m_widget->getDrawWidgetProxy()->getZoom();
|
||||
const PDFReal zoomStep = std::pow(PDFDrawWidgetProxy::ZOOM_STEP, static_cast<PDFReal>(angleDeltaY) / static_cast<PDFReal>(QWheelEvent::DefaultDeltasPerStep));
|
||||
const PDFReal newZoom = zoom * zoomStep;
|
||||
m_widget->getDrawWidgetProxy()->zoom(newZoom);
|
||||
proxy->zoom(newZoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -211,8 +212,27 @@ void PDFDrawWidget::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
const QPoint angleDelta = event->angleDelta();
|
||||
const bool shiftModifier = keyboardModifiers.testFlag(Qt::ShiftModifier);
|
||||
const int stepVertical = shiftModifier ? m_widget->getVerticalScrollbar()->pageStep() : m_widget->getVerticalScrollbar()->singleStep();
|
||||
const int stepHorizontal = shiftModifier ? m_widget->getHorizontalScrollbar()->pageStep() : m_widget->getHorizontalScrollbar()->singleStep();
|
||||
int stepVertical = 0;
|
||||
int stepHorizontal = shiftModifier ? m_widget->getHorizontalScrollbar()->pageStep() : m_widget->getHorizontalScrollbar()->singleStep();
|
||||
|
||||
if (proxy->isBlockMode())
|
||||
{
|
||||
// In block mode, we must calculate pixel offsets differently - scrollbars corresponds to indices of blocks,
|
||||
// not to the pixels.
|
||||
QRect boundingBox = proxy->getPagesIntersectingRectBoundingBox(this->rect());
|
||||
|
||||
if (boundingBox.isEmpty())
|
||||
{
|
||||
// This occurs, when we have not opened a document
|
||||
boundingBox = this->rect();
|
||||
}
|
||||
|
||||
stepVertical = shiftModifier ? boundingBox.height() : boundingBox.height() / 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
stepVertical = shiftModifier ? m_widget->getVerticalScrollbar()->pageStep() : m_widget->getVerticalScrollbar()->singleStep();
|
||||
}
|
||||
|
||||
const int scrollVertical = stepVertical * static_cast<PDFReal>(angleDelta.y()) / static_cast<PDFReal>(QWheelEvent::DefaultDeltasPerStep);
|
||||
const int scrollHorizontal = stepHorizontal * static_cast<PDFReal>(angleDelta.x()) / static_cast<PDFReal>(QWheelEvent::DefaultDeltasPerStep);
|
||||
@ -220,7 +240,16 @@ void PDFDrawWidget::wheelEvent(QWheelEvent* event)
|
||||
scrollByPixels = QPoint(scrollHorizontal, scrollVertical);
|
||||
}
|
||||
|
||||
m_widget->getDrawWidgetProxy()->scrollByPixels(scrollByPixels);
|
||||
QPoint offset = proxy->scrollByPixels(scrollByPixels);
|
||||
|
||||
if (offset.y() == 0 && scrollByPixels.y() != 0 && proxy->isBlockMode())
|
||||
{
|
||||
// We must move to another block (we are in block mode)
|
||||
bool up = scrollByPixels.y() > 0;
|
||||
|
||||
m_widget->getVerticalScrollbar()->setValue(m_widget->getVerticalScrollbar()->value() + (up ? -1 : 1));
|
||||
proxy->scrollByPixels(QPoint(0, up ? std::numeric_limits<int>::min() : std::numeric_limits<int>::max()));
|
||||
}
|
||||
}
|
||||
|
||||
event->accept();
|
||||
|
@ -262,11 +262,12 @@ void PDFPageContentProcessor::reportRenderError(RenderErrorType type, QString me
|
||||
m_errorList.append(PDFRenderError(type, qMove(message)));
|
||||
}
|
||||
|
||||
void PDFPageContentProcessor::performPathPainting(const QPainterPath& path, bool stroke, bool fill, Qt::FillRule fillRule)
|
||||
void PDFPageContentProcessor::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
|
||||
{
|
||||
Q_UNUSED(path);
|
||||
Q_UNUSED(stroke);
|
||||
Q_UNUSED(fill);
|
||||
Q_UNUSED(text);
|
||||
Q_UNUSED(fillRule);
|
||||
}
|
||||
|
||||
@ -1246,7 +1247,7 @@ void PDFPageContentProcessor::operatorPathStroke()
|
||||
if (!m_currentPath.isEmpty())
|
||||
{
|
||||
m_currentPath.setFillRule(Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, false, Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, false, false, Qt::WindingFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1258,7 +1259,7 @@ void PDFPageContentProcessor::operatorPathCloseStroke()
|
||||
{
|
||||
m_currentPath.closeSubpath();
|
||||
m_currentPath.setFillRule(Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, false, Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, false, false, Qt::WindingFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1268,7 +1269,7 @@ void PDFPageContentProcessor::operatorPathFillWinding()
|
||||
if (!m_currentPath.isEmpty())
|
||||
{
|
||||
m_currentPath.setFillRule(Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, false, true, Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, false, true, false, Qt::WindingFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1278,7 +1279,7 @@ void PDFPageContentProcessor::operatorPathFillEvenOdd()
|
||||
if (!m_currentPath.isEmpty())
|
||||
{
|
||||
m_currentPath.setFillRule(Qt::OddEvenFill);
|
||||
performPathPainting(m_currentPath, false, true, Qt::OddEvenFill);
|
||||
performPathPainting(m_currentPath, false, true, false, Qt::OddEvenFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1288,7 +1289,7 @@ void PDFPageContentProcessor::operatorPathFillStrokeWinding()
|
||||
if (!m_currentPath.isEmpty())
|
||||
{
|
||||
m_currentPath.setFillRule(Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, true, Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, true, false, Qt::WindingFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1298,7 +1299,7 @@ void PDFPageContentProcessor::operatorPathFillStrokeEvenOdd()
|
||||
if (!m_currentPath.isEmpty())
|
||||
{
|
||||
m_currentPath.setFillRule(Qt::OddEvenFill);
|
||||
performPathPainting(m_currentPath, true, true, Qt::OddEvenFill);
|
||||
performPathPainting(m_currentPath, true, true, false, Qt::OddEvenFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1309,7 +1310,7 @@ void PDFPageContentProcessor::operatorPathCloseFillStrokeWinding()
|
||||
{
|
||||
m_currentPath.closeSubpath();
|
||||
m_currentPath.setFillRule(Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, true, Qt::WindingFill);
|
||||
performPathPainting(m_currentPath, true, true, false, Qt::WindingFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1320,7 +1321,7 @@ void PDFPageContentProcessor::operatorPathCloseFillStrokeEvenOdd()
|
||||
{
|
||||
m_currentPath.closeSubpath();
|
||||
m_currentPath.setFillRule(Qt::OddEvenFill);
|
||||
performPathPainting(m_currentPath, true, true, Qt::OddEvenFill);
|
||||
performPathPainting(m_currentPath, true, true, false, Qt::OddEvenFill);
|
||||
m_currentPath = QPainterPath();
|
||||
}
|
||||
}
|
||||
@ -1809,7 +1810,7 @@ void PDFPageContentProcessor::drawText(const TextSequence& textSequence)
|
||||
{
|
||||
QMatrix textRenderingMatrix = adjustMatrix * textMatrix;
|
||||
QPainterPath transformedGlyph = textRenderingMatrix.map(glyphPath);
|
||||
performPathPainting(transformedGlyph, stroke, fill, transformedGlyph.fillRule());
|
||||
performPathPainting(transformedGlyph, stroke, fill, true, transformedGlyph.fillRule());
|
||||
|
||||
if (clipped)
|
||||
{
|
||||
|
@ -347,8 +347,9 @@ protected:
|
||||
/// \param path Path, which should be drawn (can be emtpy - in that case nothing happens)
|
||||
/// \param stroke Stroke the path
|
||||
/// \param fill Fill the path using given rule
|
||||
/// \param text Is text being drawn?
|
||||
/// \param fillRule Fill rule used in the fill mode
|
||||
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, Qt::FillRule fillRule);
|
||||
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule);
|
||||
|
||||
/// This function has to be implemented in the client drawing implementation, it should
|
||||
/// clip along the path (intersect with current clipping path).
|
||||
|
@ -40,7 +40,7 @@ PDFPainter::~PDFPainter()
|
||||
m_painter->restore();
|
||||
}
|
||||
|
||||
void PDFPainter::performPathPainting(const QPainterPath& path, bool stroke, bool fill, Qt::FillRule fillRule)
|
||||
void PDFPainter::performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule)
|
||||
{
|
||||
if ((!stroke && !fill) || path.isEmpty())
|
||||
{
|
||||
@ -48,6 +48,10 @@ void PDFPainter::performPathPainting(const QPainterPath& path, bool stroke, bool
|
||||
return;
|
||||
}
|
||||
|
||||
// Set antialiasing
|
||||
const bool antialiasing = (text && m_features.testFlag(PDFRenderer::TextAntialiasing)) || (!text && m_features.testFlag(PDFRenderer::Antialiasing));
|
||||
m_painter->setRenderHint(QPainter::Antialiasing, antialiasing);
|
||||
|
||||
if (stroke)
|
||||
{
|
||||
m_painter->setPen(getCurrentPen());
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
virtual ~PDFPainter() override;
|
||||
|
||||
protected:
|
||||
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, Qt::FillRule fillRule) override;
|
||||
virtual void performPathPainting(const QPainterPath& path, bool stroke, bool fill, bool text, Qt::FillRule fillRule) override;
|
||||
virtual void performClipping(const QPainterPath& path, Qt::FillRule fillRule) override;
|
||||
virtual void performUpdateGraphicsState(const PDFPageContentProcessorState& state) override;
|
||||
virtual void performSaveGraphicState(ProcessOrder order) override;
|
||||
|
@ -30,9 +30,8 @@ PDFRenderer::PDFRenderer(const PDFDocument* document, const PDFFontCache* fontCa
|
||||
Q_ASSERT(document);
|
||||
}
|
||||
|
||||
// TODO: Dodelat features, napr. antialiasing
|
||||
// TODO: Dodelat rotovani stranek
|
||||
// TODO: Dodelat obrazky
|
||||
// TODO: Dodelat obrazky - SMOOTH
|
||||
|
||||
QList<PDFRenderError> PDFRenderer::render(QPainter* painter, const QRectF& rectangle, size_t pageIndex) const
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user