File indexing completed on 2024-05-19 04:35:34
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0003 0004 */ 0005 0006 #include "magnifierview.h" 0007 0008 #include <QPainter> 0009 0010 #include "core/document.h" 0011 #include "core/generator.h" 0012 #include "gui/pagepainter.h" 0013 #include "gui/priorities.h" 0014 0015 static const int SCALE = 10; 0016 0017 MagnifierView::MagnifierView(Okular::Document *document, QWidget *parent) 0018 : QWidget(parent) 0019 , m_document(document) 0020 , m_page(nullptr) 0021 { 0022 document->addObserver(this); 0023 } 0024 0025 MagnifierView::~MagnifierView() 0026 { 0027 m_document->removeObserver(this); 0028 } 0029 0030 void MagnifierView::notifySetup(const QVector<Okular::Page *> &pages, int setupFlags) 0031 { 0032 if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) { 0033 return; 0034 } 0035 0036 m_pages = pages; 0037 m_page = nullptr; 0038 m_current = -1; 0039 } 0040 0041 void MagnifierView::notifyPageChanged(int page, int flags) 0042 { 0043 Q_UNUSED(page); 0044 Q_UNUSED(flags); 0045 0046 if (isVisible()) { 0047 update(); 0048 } 0049 } 0050 0051 bool MagnifierView::canUnloadPixmap(int page) const 0052 { 0053 return (page != m_current); 0054 } 0055 0056 void MagnifierView::notifyCurrentPageChanged(int previous, int current) 0057 { 0058 Q_UNUSED(previous); 0059 0060 if (current != m_current) { 0061 m_current = current; 0062 m_page = m_pages[current]; 0063 0064 if (isVisible()) { 0065 requestPixmap(); 0066 update(); 0067 } 0068 } 0069 } 0070 0071 void MagnifierView::updateView(const Okular::NormalizedPoint &p, const Okular::Page *page) 0072 { 0073 m_viewpoint = p; 0074 0075 if (page != m_page) // ok, we are screwed 0076 { 0077 m_page = page; 0078 m_current = page->number(); 0079 } 0080 0081 if (isVisible()) { 0082 requestPixmap(); 0083 update(); 0084 } 0085 } 0086 0087 void MagnifierView::paintEvent(QPaintEvent *e) 0088 { 0089 Q_UNUSED(e); 0090 0091 QPainter p(this); 0092 0093 if (m_page) { 0094 QRect where = QRect(0, 0, width(), height()); 0095 PagePainter::paintCroppedPageOnPainter(&p, m_page, this, 0, m_page->width() * SCALE, m_page->height() * SCALE, where, normalizedView(), nullptr); 0096 } 0097 0098 drawTicks(&p); 0099 } 0100 0101 void MagnifierView::move(int x, int y) 0102 { 0103 QWidget::move(x, y); 0104 requestPixmap(); 0105 } 0106 0107 void MagnifierView::requestPixmap() 0108 { 0109 if (!m_page) { 0110 return; 0111 } 0112 const int full_width = m_page->width() * SCALE; 0113 const int full_height = m_page->height() * SCALE; 0114 0115 Okular::NormalizedRect nrect = normalizedView(); 0116 0117 if (!m_page->hasPixmap(this, full_width, full_height, nrect)) { 0118 Okular::PixmapRequest *p = new Okular::PixmapRequest(this, m_current, full_width, full_height, devicePixelRatioF(), PAGEVIEW_PRIO, Okular::PixmapRequest::Asynchronous); 0119 0120 if (m_page->hasTilesManager(this)) { 0121 p->setTile(true); 0122 } 0123 0124 // request a little bit bigger rectangle then currently viewed, but not the full scale page 0125 const double rect_width = (nrect.right - nrect.left) * 0.5, rect_height = (nrect.bottom - nrect.top) * 0.5; 0126 0127 const double top = qMax(nrect.top - rect_height, 0.0); 0128 const double bottom = qMin(nrect.bottom + rect_height, 1.0); 0129 const double left = qMax(nrect.left - rect_width, 0.0); 0130 const double right = qMin(nrect.right + rect_width, 1.0); 0131 0132 p->setNormalizedRect(Okular::NormalizedRect(left, top, right, bottom)); 0133 0134 m_document->requestPixmaps({p}); 0135 } 0136 } 0137 0138 Okular::NormalizedRect MagnifierView::normalizedView() const 0139 { 0140 double h = (double)height() / (SCALE * m_page->height() * 2); 0141 double w = (double)width() / (SCALE * m_page->width() * 2); 0142 return Okular::NormalizedRect(m_viewpoint.x - w, m_viewpoint.y - h, m_viewpoint.x + w, m_viewpoint.y + h); 0143 } 0144 0145 void MagnifierView::drawTicks(QPainter *p) 0146 { 0147 p->save(); 0148 0149 p->setPen(QPen(Qt::black, 0)); 0150 // the cross 0151 p->drawLine(width() / 2, 0, width() / 2, height() - 1); 0152 p->drawLine(0, height() / 2, width() - 1, height() / 2); 0153 0154 // the borders 0155 p->drawLine(0, 0, width() - 1, 0); 0156 p->drawLine(width() - 1, 0, width() - 1, height() - 1); 0157 p->drawLine(0, height() - 1, width() - 1, height() - 1); 0158 p->drawLine(0, height() - 1, 0, 0); 0159 0160 // ticks 0161 // TODO possibility to switch units (pt, mm, cc, in, printing dots) 0162 float ps = (float)SCALE * 5; // how much pixels in widget is one pixel in document * how often 0163 int tw = 10; // tick size in pixels 0164 0165 for (float x = 0; x < width(); x += ps) { 0166 p->drawLine(x, 1, x, tw); 0167 p->drawLine(x, height() - 1, x, height() - tw - 1); 0168 p->drawLine(1, x, tw, x); 0169 p->drawLine(width() - 1, x, width() - tw - 1, x); 0170 } 0171 0172 p->restore(); 0173 } 0174 0175 #include "moc_magnifierview.cpp"