/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "magnifierview.h" #include #include "core/document.h" #include "core/generator.h" #include "pagepainter.h" #include "priorities.h" static const int SCALE = 10; MagnifierView::MagnifierView(Okular::Document* document, QWidget* parent) : QWidget(parent) , m_document(document) , m_page(nullptr) { document->addObserver(this); } MagnifierView::~MagnifierView() { m_document->removeObserver(this); } void MagnifierView::notifySetup(const QVector< Okular::Page* >& pages, int setupFlags) { if (!(setupFlags & Okular::DocumentObserver::DocumentChanged)) { return; } m_pages = pages; m_page = nullptr; m_current = -1; } void MagnifierView::notifyPageChanged(int page, int flags) { Q_UNUSED(page); Q_UNUSED(flags); if (isVisible()) { update(); } } bool MagnifierView::canUnloadPixmap(int page) const { return (page != m_current); } void MagnifierView::notifyCurrentPageChanged(int previous, int current) { Q_UNUSED(previous); if (current != m_current) { m_current = current; m_page = m_pages[current]; if (isVisible()) { requestPixmap(); update(); } } } void MagnifierView::updateView( const Okular::NormalizedPoint& p, const Okular::Page *page ) { m_viewpoint = p; if (page != m_page) // ok, we are screwed { m_page = page; m_current = page->number(); } if (isVisible()) { requestPixmap(); update(); } } void MagnifierView::paintEvent(QPaintEvent* e) { Q_UNUSED(e); QPainter p(this); if (m_page) { QRect where = QRect(0, 0, width(), height()); PagePainter::paintCroppedPageOnPainter(&p, m_page, this, 0, m_page->width() * SCALE, m_page->height() * SCALE, where, normalizedView(), nullptr); } drawTicks(&p); } void MagnifierView::move( int x, int y) { QWidget::move( x, y ); requestPixmap(); } void MagnifierView::requestPixmap() { const int full_width = m_page->width() * SCALE; const int full_height = m_page->height() * SCALE; Okular::NormalizedRect nrect = normalizedView(); if (m_page && !m_page->hasPixmap( this, full_width, full_height, nrect )) { QLinkedList< Okular::PixmapRequest * > requestedPixmaps; Okular::PixmapRequest *p = new Okular::PixmapRequest( this, m_current, full_width, full_height, PAGEVIEW_PRIO, Okular::PixmapRequest::Asynchronous ); if ( m_page->hasTilesManager( this ) ) { p->setTile( true ); } // request a little bit bigger rectangle then currently viewed, but not the full scale page const double rect_width = (nrect.right - nrect.left) * 0.5, rect_height = (nrect.bottom - nrect.top) * 0.5; const double top = qMax(nrect.top - rect_height, 0.0); const double bottom = qMin(nrect.bottom + rect_height, 1.0); const double left = qMax(nrect.left - rect_width, 0.0); const double right = qMin(nrect.right + rect_width, 1.0); p->setNormalizedRect( Okular::NormalizedRect(left, top, right, bottom) ); requestedPixmaps.push_back( p ); m_document->requestPixmaps( requestedPixmaps ); } } Okular::NormalizedRect MagnifierView::normalizedView() const { double h = (double)height() / (SCALE * m_page->height() * 2); double w = (double)width() / (SCALE * m_page->width() * 2); return Okular::NormalizedRect(m_viewpoint.x - w, m_viewpoint.y - h, m_viewpoint.x + w, m_viewpoint.y + h); } void MagnifierView::drawTicks( QPainter *p ) { p->save(); p->setPen(QPen(Qt::black, 0)); // the cross p->drawLine(width() / 2, 0, width() / 2, height() - 1); p->drawLine(0, height() / 2, width() - 1, height() / 2); // the borders p->drawLine(0, 0, width() - 1, 0); p->drawLine(width() - 1, 0, width() - 1, height() - 1); p->drawLine(0, height() - 1, width() - 1, height() - 1); p->drawLine(0, height() - 1, 0, 0); // ticks // TODO possibility to switch units (pt, mm, cc, in, printing dots) float ps = (float)SCALE * 5;// how much pixels in widget is one pixel in document * how often int tw = 10; // tick size in pixels for ( float x = 0; x < width(); x += ps ) { p->drawLine(x, 1, x, tw); p->drawLine(x, height() - 1, x, height() - tw - 1); p->drawLine(1, x, tw, x); p->drawLine(width() - 1, x, width() - tw - 1, x); } p->restore(); } #include "moc_magnifierview.cpp"