Skip to content

Commit

Permalink
Fixed blurry pages
Browse files Browse the repository at this point in the history
Screens with a device pixel ratio of or more less than 1 (e.g. screens which have a 125% zoom) had problems with blurry pages. ZThis commit fixed it by calculating the dpr value into the scale during image generation.
  • Loading branch information
DavidLazarescu committed Nov 1, 2023
1 parent bbccfa5 commit 2ae4555
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 61 deletions.
45 changes: 23 additions & 22 deletions src/adapters/controllers/page_controller.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
#include "page_controller.hpp"
#include "fz_utils.hpp"
#include "mupdf/classes.h"
#include "mupdf/classes2.h"

using namespace application::core;

namespace adapters::controllers
{

PageController::PageController(mupdf::FzDocument* document, int pageNumber) :
m_pageGenerator(document, pageNumber)
PageController::PageController(mupdf::FzDocument* document, int pageNumber,
double dpr) :
m_pageGenerator(document, pageNumber),
m_dpr(dpr)
{
}

int PageController::getWidth()
{
return m_pageGenerator.getWidth() * m_matrix.a;
return m_pageGenerator.getWidth() * m_matrix.a / m_dpr;
}

int PageController::getHeight()
{
return m_pageGenerator.getHeight() * m_matrix.d;
return m_pageGenerator.getHeight() * m_matrix.d / m_dpr;
}

int PageController::getXOffset() const
Expand All @@ -35,8 +36,8 @@ int PageController::getYOffset() const

void PageController::setZoom(float zoom)
{
m_matrix.a = zoom;
m_matrix.d = zoom;
m_matrix.a = zoom * m_dpr;
m_matrix.d = zoom * m_dpr;

m_pageImageOutdated = true;
m_selectionRectsOutdated = true;
Expand Down Expand Up @@ -76,23 +77,23 @@ QImage PageController::renderPage()

bool PageController::pointIsAboveText(const QPointF& point)
{
auto fzPoint = utils::qPointToFzPoint(point);
auto fzPoint = utils::qPointToFzPoint(point, m_dpr);
utils::restoreFzPoint(fzPoint, m_matrix);

return m_pageGenerator.pointIsAboveText(fzPoint);
}

bool PageController::pointIsAboveLink(const QPointF& point)
{
auto fzPoint = utils::qPointToFzPoint(point);
auto fzPoint = utils::qPointToFzPoint(point, m_dpr);
utils::restoreFzPoint(fzPoint, m_matrix);

return m_pageGenerator.pointIsAboveLink(fzPoint);
}

const char* PageController::getLinkUriAtPoint(const QPointF& point)
{
auto fzPoint = utils::qPointToFzPoint(point);
auto fzPoint = utils::qPointToFzPoint(point, m_dpr);
utils::restoreFzPoint(fzPoint, m_matrix);

return m_pageGenerator.getLinkAtPoint(fzPoint).uri();
Expand All @@ -118,8 +119,8 @@ const QList<QRectF>& PageController::getBufferedSelectionRects()

void PageController::generateSelectionRects(QPointF start, QPointF end)
{
auto fzStart = utils::qPointToFzPoint(start);
auto fzEnd = utils::qPointToFzPoint(end);
auto fzStart = utils::qPointToFzPoint(start, m_dpr);
auto fzEnd = utils::qPointToFzPoint(end, m_dpr);
utils::restoreFzPoint(fzStart, m_matrix);
utils::restoreFzPoint(fzEnd, m_matrix);

Expand All @@ -138,43 +139,43 @@ void PageController::clearBufferedSelectionRects()
QPair<QPointF, QPointF> PageController::getPositionsForWordSelection(
QPointF start, QPointF end)
{
auto fzStart = utils::qPointToFzPoint(start);
auto fzEnd = utils::qPointToFzPoint(end);
auto fzStart = utils::qPointToFzPoint(start, m_dpr);
auto fzEnd = utils::qPointToFzPoint(end, m_dpr);
utils::restoreFzPoint(fzStart, m_matrix);
utils::restoreFzPoint(fzEnd, m_matrix);

auto res = m_pageGenerator.getPositionsForWordSelection(fzStart, fzEnd);
res.first = res.first.fz_transform_point(m_matrix);
res.second = res.second.fz_transform_point(m_matrix);

return QPointFPair(utils::fzPointToQPoint(res.first),
utils::fzPointToQPoint(res.second));
return QPointFPair(utils::fzPointToQPoint(res.first, m_dpr),
utils::fzPointToQPoint(res.second, m_dpr));
}

QPair<QPointF, QPointF> PageController::getPositionsForLineSelection(
QPointF point)
{
auto fzPoint = utils::qPointToFzPoint(point);
auto fzPoint = utils::qPointToFzPoint(point, m_dpr);
utils::restoreFzPoint(fzPoint, m_matrix);

auto res = m_pageGenerator.getPositionsForLineSelection(fzPoint);
res.first = res.first.fz_transform_point(m_matrix);
res.second = res.second.fz_transform_point(m_matrix);

return QPointFPair(utils::fzPointToQPoint(res.first),
utils::fzPointToQPoint(res.second));
return QPointFPair(utils::fzPointToQPoint(res.first, m_dpr),
utils::fzPointToQPoint(res.second, m_dpr));
}

QString PageController::getTextFromSelection(const QPointF& start,
const QPointF& end)
{
auto fzStart = utils::qPointToFzPoint(start);
auto fzEnd = utils::qPointToFzPoint(end);
auto fzStart = utils::qPointToFzPoint(start, m_dpr);
auto fzEnd = utils::qPointToFzPoint(end, m_dpr);
utils::restoreFzPoint(fzStart, m_matrix);
utils::restoreFzPoint(fzEnd, m_matrix);

auto res = m_pageGenerator.getTextFromSelection(fzStart, fzEnd);
return QString::fromStdString(res);
}

} // namespace adapters::controllers
} // namespace adapters::controllers
11 changes: 9 additions & 2 deletions src/adapters/controllers/page_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class PageController : public IPageController
Q_OBJECT

public:
PageController(mupdf::FzDocument* document, int pageNumber);
PageController(mupdf::FzDocument* document, int pageNumber, double dpr);

int getWidth() override;
int getHeight() override;
Expand Down Expand Up @@ -49,6 +49,13 @@ class PageController : public IPageController
int m_pageXOffset = 0;
int m_pageYOffset = 0;

// The dpr is the "device pixel ratio" which is a ratio (e.g. 1.25) between
// the device pixels and the logical pixels. For example, if the screen is
// scaled by 125% via software, the dpr will be 1.25.
// We need to make sure that the page is rendered with the correct dpr so
// that the page is not blurry.
double m_dpr = 1.0;

// Image caching
bool m_pageImageOutdated = true;
QImage m_pageImage;
Expand All @@ -60,4 +67,4 @@ class PageController : public IPageController
using QPointFPair = QPair<QPointF, QPointF>;
};

} // namespace adapters::controllers
} // namespace adapters::controllers
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ADAPTERS_EXPORT ILibraryController : public QObject

Q_INVOKABLE virtual void syncWithServer() = 0;
Q_INVOKABLE virtual int addBook(const QString& path,
int projectGutenbergId) = 0;
int projectGutenbergId = 0) = 0;
Q_INVOKABLE virtual int deleteBook(const QString& uuid) = 0;
Q_INVOKABLE virtual int deleteAllBooks() = 0;
Q_INVOKABLE virtual int uninstallBook(const QString& uuid) = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/interfaces/controllers/i_page_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ class ADAPTERS_EXPORT IPageController : public QObject
void pageOffsetsChanged(int xOffset, int yOffset);
};

} // namespace adapters
} // namespace adapters
2 changes: 1 addition & 1 deletion src/application/core/page_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,4 @@ mupdf::FzLink PageGenerator::getLinkAtPoint(mupdf::FzPoint point)
return mupdf::FzLink();
}

} // namespace application::core
} // namespace application::core
11 changes: 6 additions & 5 deletions src/application/core/utils/fz_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,15 @@ inline QImage qImageFromPixmap(mupdf::FzPixmap pixmap)
return image;
}

inline mupdf::FzPoint qPointToFzPoint(const QPointF& qPoint)
inline mupdf::FzPoint qPointToFzPoint(const QPointF& qPoint, double scaler = 1)
{
return mupdf::FzPoint(qPoint.x(), qPoint.y());
return mupdf::FzPoint(qPoint.x() * scaler, qPoint.y() * scaler);
}

inline QPointF fzPointToQPoint(const mupdf::FzPoint& fzPoint)
inline QPointF fzPointToQPoint(const mupdf::FzPoint& fzPoint,
double invScaler = 1)
{
return QPointF(fzPoint.x, fzPoint.y);
return QPointF(fzPoint.x / invScaler, fzPoint.y / invScaler);
}

/**
Expand Down Expand Up @@ -163,4 +164,4 @@ inline mupdf::FzPoint movePoint(const mupdf::FzPoint& point, int x, int y)
return fz_make_point(point.x + x, point.y + y);
}

} // namespace application::core::utils
} // namespace application::core::utils
75 changes: 46 additions & 29 deletions src/presentation/modules/CppElements/page_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ void PageView::setBookController(BookController* newBookController)
m_bookController = newBookController;

m_pageController = std::make_unique<PageController>(
m_bookController->getFzDocument(), m_pageNumber);
m_bookController->getFzDocument(), m_pageNumber,
window()->devicePixelRatio());
m_pageController->setZoom(m_bookController->getZoom());

// Setup connections to the BookController
Expand All @@ -63,9 +64,14 @@ void PageView::setBookController(BookController* newBookController)
// The points received from this signal are relative to a zoom
// of 1, but all of the methods in this class handle points as
// if they have the currentZoom applied, so we need to scale it.
// We need to divide by the dpr since the lower level methods
// expect the caller not to know anything about the dpr, but the
// current zoom we get from the page controller is zoom * dpr.
// Thus we need to reset it to the zoom without the dpr.
auto zoom = m_pageController->getZoom();
left = utils::scalePointToCurrentZoom(left, 1, zoom);
right = utils::scalePointToCurrentZoom(right, 1, zoom);
auto dpr = window()->devicePixelRatio();
left = utils::scalePointToCurrentZoom(left, 1, zoom / dpr);
right = utils::scalePointToCurrentZoom(right, 1, zoom / dpr);

m_selectionStart = left;
m_selectionEnd = right;
Expand Down Expand Up @@ -213,7 +219,8 @@ void PageView::handleClickingOnHighlight(const Highlight* highlight)
for(auto& rect : rects)
{
auto qRectF = rect.getQRect();
utils::scaleQRectFToZoom(qRectF, m_bookController->getZoom());
utils::scaleQRectFToZoom(
qRectF, m_pageController->getZoom() / window()->devicePixelRatio());
qRects.append(qRectF);
}
auto positions = getCenterXAndTopYFromRects(qRects);
Expand Down Expand Up @@ -252,8 +259,18 @@ void PageView::mouseReleaseEvent(QMouseEvent* event)
}
else if(!m_startedMousePressOnHighlight)
{
auto positions = getCenterXAndTopYFromRects(
m_pageController->getBufferedSelectionRects());
auto rects = m_pageController->getBufferedSelectionRects();
QList<QRectF> restoredRects;
restoredRects.reserve(rects.size());
for(auto rect : rects)
{
utils::restoreQRect(rect, m_pageController->getZoom());
utils::scaleQRectFToZoom(rect, m_pageController->getZoom() /
window()->devicePixelRatio());
restoredRects.push_back(rect);
}

auto positions = getCenterXAndTopYFromRects(restoredRects);

emit m_bookController->textSelectionFinished(positions.first,
positions.second);
Expand All @@ -262,6 +279,28 @@ void PageView::mouseReleaseEvent(QMouseEvent* event)
m_doubleClickHold = false;
}

QPair<float, float> PageView::getCenterXAndTopYFromRects(
const QList<QRectF>& rects)
{
float mostLeftX = std::numeric_limits<float>::max();
float mostRightX = 0;
float topY = std::numeric_limits<float>::max();
for(auto& rect : rects)
{
if(rect.x() < mostLeftX)
mostLeftX = rect.x();

if(rect.x() + rect.width() > mostRightX)
mostRightX = rect.x() + rect.width();

if(rect.top() < topY)
topY = rect.top();
}

auto centerX = (mostLeftX + mostRightX) / 2;
return { centerX, topY };
}

void PageView::mouseMoveEvent(QMouseEvent* event)
{
if(event->buttons() == Qt::RightButton)
Expand Down Expand Up @@ -316,28 +355,6 @@ void PageView::paintSelectionOnPage(QPainter& painter)
}
}

QPair<float, float> PageView::getCenterXAndTopYFromRects(
const QList<QRectF>& rects)
{
float mostLeftX = std::numeric_limits<float>::max();
float mostRightX = 0;
float topY = std::numeric_limits<float>::max();
for(auto& rect : rects)
{
if(rect.x() < mostLeftX)
mostLeftX = rect.x();

if(rect.x() + rect.width() > mostRightX)
mostRightX = rect.x() + rect.width();

if(rect.top() < topY)
topY = rect.top();
}

auto centerX = (mostLeftX + mostRightX) / 2;
return { centerX, topY };
}

void PageView::paintHighlightsOnPage(QPainter& painter)
{
for(auto& highlight : m_bookController->getHighlights())
Expand Down Expand Up @@ -625,4 +642,4 @@ float PageView::getYOffset() const
return m_pageController->getYOffset();
}

} // namespace cpp_elements
} // namespace cpp_elements

0 comments on commit 2ae4555

Please sign in to comment.