Use DPI of current screen for PDF rendering

Includes some fixes from Albert:
 * kscreen cmake fixes
   Don't make libkscreen mandatory, give the proper version we need
 * Fix the @since
 * Kill Resolution and use a QSizeF
   I first thought QSizeF didn't make sense, but well what's a dpi if not a number of pixels in width and some others in height?
 * Remove unwanted const
 * Remove unneeded utils.h includes
 * Fix comments on realDPIXY()
 * Make it compile in non X11

REVIEW: 111829
remotes/origin/KDE/4.13
Eugene Shalygin 12 years ago committed by Albert Astals Cid
parent c5f1b35df1
commit ed35594627
  1. 8
      CMakeLists.txt
  2. 3
      config-okular.h.cmake
  3. 12
      core/document.cpp
  4. 15
      core/generator.cpp
  5. 17
      core/generator.h
  6. 1
      core/generator_p.h
  7. 58
      core/utils.cpp
  8. 15
      core/utils.h
  9. 19
      generators/poppler/generator_pdf.cpp
  10. 4
      generators/poppler/generator_pdf.h

@ -10,12 +10,16 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules)
macro_optional_find_package(QImageBlitz)
macro_log_feature(QIMAGEBLITZ_FOUND "QImageBlitz" "An image effects library" "http://sourceforge.net/projects/qimageblitz" TRUE "kdesupport" "Required to build Okular.")
macro_optional_find_package(LibKScreen)
macro_log_feature(LibKScreen_FOUND "LibKScreen" "KDE screen management library" "https://projects.kde.org/projects/kdereview/libkscreen" FALSE "1.0.2" "DPI detection support")
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${KDE4_INCLUDES}
${QIMAGEBLITZ_INCLUDES}
${LibKScreen_INCLUDE_DIR}
)
add_subdirectory( active )
@ -131,6 +135,10 @@ ENDIF(APPLE)
target_link_libraries(okularcore ${OKULAR_IOKIT} ${KDE4_KIO_LIBS} ${KDE4_PHONON_LIBRARY} ${KDE4_KJSAPI_LIBRARY} ${MATH_LIB} ${KDE4_THREADWEAVER_LIBRARY} )
if(LibKScreen_FOUND)
target_link_libraries(okularcore ${LibKScreen_LIBRARY})
endif(LibKScreen_FOUND)
set_target_properties(okularcore PROPERTIES VERSION 3.0.0 SOVERSION 3 )
install(TARGETS okularcore ${INSTALL_TARGETS_DEFAULT_ARGS} )

@ -1,2 +1,5 @@
/* Defines if force the use DRM in okular */
#define OKULAR_FORCE_DRM ${_OKULAR_FORCE_DRM}
/* Defines if LibKScreen is present */
#define HAVE_LIBKSCREEN ${LibKScreen_FOUND}

@ -84,6 +84,7 @@
#include "view.h"
#include "view_p.h"
#include "form.h"
#include "utils.h"
#include <memory>
@ -267,6 +268,14 @@ QString DocumentPrivate::localizedSize(const QSizeF &size) const
inchesHeight = size.height() / 72.0;
break;
case Generator::Pixels:
{
const QSizeF dpi = m_generator->dpi();
inchesWidth = size.width() / dpi.width();
inchesHeight = size.height() / dpi.height();
}
break;
case Generator::None:
break;
}
@ -917,6 +926,9 @@ bool DocumentPrivate::openDocumentInternal( const KService::Ptr& offer, bool iss
QObject::connect( m_generator, SIGNAL(notice(QString,int)), m_parent, SIGNAL(notice(QString,int)) );
QApplication::setOverrideCursor( Qt::WaitCursor );
m_generator->setDPI(Utils::realDpi(m_widget));
bool openOk = false;
if ( !isstdin )
{

@ -31,7 +31,8 @@ GeneratorPrivate::GeneratorPrivate()
: m_document( 0 ),
mPixmapGenerationThread( 0 ), mTextPageGenerationThread( 0 ),
m_mutex( 0 ), m_threadsMutex( 0 ), mPixmapReady( true ), mTextPageReady( true ),
m_closing( false ), m_closingLoop( 0 )
m_closing( false ), m_closingLoop( 0 ),
m_dpi(72.0, 72.0)
{
}
@ -422,6 +423,18 @@ const SourceReference * Generator::dynamicSourceReference( int /*pageNr*/, doubl
return 0;
}
void Generator::setDPI(const QSizeF & dpi)
{
Q_D( Generator );
d->m_dpi = dpi;
}
QSizeF Generator::dpi() const
{
Q_D( const Generator );
return d->m_dpi;
}
PixmapRequest::PixmapRequest( DocumentObserver *observer, int pageNumber, int width, int height, int priority, PixmapRequestFeatures features )
: d( new PixmapRequestPrivate )
{

@ -20,6 +20,7 @@
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QSizeF>
#include <QtCore/QString>
#include <QtCore/QVariant>
#include <QtCore/QVector>
@ -308,7 +309,8 @@ class OKULAR_EXPORT Generator : public QObject
enum PageSizeMetric
{
None, ///< The page size is not defined in a physical metric.
Points ///< The page size is given in 1/72 inches.
Points, ///< The page size is given in 1/72 inches.
Pixels ///< The page size is given in screen pixels @since 0.19 (KDE 4.13)
};
/**
@ -384,6 +386,13 @@ class OKULAR_EXPORT Generator : public QObject
*/
bool hasFeature( GeneratorFeature feature ) const;
/**
* Update DPI of the generator
*
* @since 0.19 (KDE 4.13)
*/
void setDPI(const QSizeF &dpi);
Q_SIGNALS:
/**
* This signal should be emitted whenever an error occurred in the generator.
@ -476,6 +485,12 @@ class OKULAR_EXPORT Generator : public QObject
*/
void updatePageBoundingBox( int page, const NormalizedRect & boundingBox );
/**
* Returns DPI, previously set via setDPI()
* @since 0.19 (KDE 4.13)
*/
QSizeF dpi() const;
protected Q_SLOTS:
/**
* Gets the font data for the given font

@ -64,6 +64,7 @@ class GeneratorPrivate
bool mTextPageReady : 1;
bool m_closing : 1;
QEventLoop *m_closingLoop;
QSizeF m_dpi;
};

@ -18,7 +18,11 @@
#include <QIODevice>
#ifdef Q_WS_X11
#include <QX11Info>
#include "config-okular.h"
#if HAVE_LIBKSCREEN
#include <kscreen/config.h>
#endif
#include <QX11Info>
#endif
#ifdef Q_WS_MAC
@ -81,6 +85,48 @@ double Utils::realDpiY()
return (double(w->height()) * 25.4) / double(w->heightMM());
}
QSizeF Utils::realDpi(QWidget* widgetOnScreen)
{
// Firstly try to retrieve DPI via LibKScreen
#if HAVE_LIBKSCREEN
KScreen::Config* config = KScreen::Config::current();
KScreen::OutputList outputs = config->outputs();
QPoint globalPos = widgetOnScreen->parentWidget() ?
widgetOnScreen->mapToGlobal(widgetOnScreen->pos()):
widgetOnScreen->pos();
QRect widgetRect(globalPos, widgetOnScreen->size());
KScreen::Output* selectedOutput = 0;
int maxArea = 0;
Q_FOREACH(KScreen::Output *output, outputs) {
if (output->currentMode()) {
QRect outputRect(output->pos(),output->currentMode()->size());
QRect intersection = outputRect.intersected(widgetRect);
int area = intersection.width()*intersection.height();
if (area > maxArea) {
maxArea = area;
selectedOutput = output;
}
}
}
if (selectedOutput) {
kDebug() << "Found widget at output #" << selectedOutput->id();
QRect outputRect(selectedOutput->pos(),selectedOutput->currentMode()->size());
QSize szMM = selectedOutput->sizeMm();
QSizeF res(static_cast<qreal>(outputRect.width())*25.4/szMM.width(),
static_cast<qreal>(outputRect.height())*25.4/szMM.height());
kDebug() << "Output DPI is " << res;
return res;
}
#endif
// this is also fallback for LibKScreen branch if KScreen::Output
// for particular widget was not found
const QDesktopWidget* desktop = QApplication::desktop();
return QSizeF((desktop->width() * 25.4) / desktop->widthMM(),
(desktop->height() * 25.4) / desktop->heightMM());
}
#elif defined(Q_WS_MAC)
/*
* Code copied from http://developer.apple.com/qa/qa2001/qa1217.html
@ -164,6 +210,11 @@ double Utils::realDpiY()
{
return dpiY();
}
QSizeF Utils::realDpi(QWidget*)
{
return QSizeF(realDpiX(), realDpiY());
}
#else
double Utils::dpiX()
@ -185,6 +236,11 @@ double Utils::realDpiY()
{
return dpiY();
}
QSizeF Utils::realDpi(QWidget*)
{
return QSizeF(realDpiX(), realDpiY());
}
#endif
inline static bool isWhite( QRgb argb ) {

@ -15,6 +15,7 @@
class QRect;
class QImage;
class QWidget;
namespace Okular
{
@ -50,6 +51,7 @@ class OKULAR_EXPORT Utils
* setting. Otherwise, returns the same as dpiX(),
*
* @since 0.9 (KDE 4.3)
* @deprecated Can not work with multi-monitor configurations
*/
static double realDpiX();
@ -60,9 +62,20 @@ class OKULAR_EXPORT Utils
* setting. Otherwise, returns the same as dpiX(),
*
* @since 0.9 (KDE 4.3)
* @deprecated Can not work with multi-monitor configurations
*/
static double realDpiY();
/**
* Return the real DPI of the display containing given widget
*
* On X11, it can indicate the real horizontal DPI value without any Xrdb
* setting. Otherwise, returns the same as realDpiX/Y(),
*
* @since 0.19 (KDE 4.13)
*/
static QSizeF realDpi(QWidget* widgetOnScreen);
/**
* Compute the smallest rectangle that contains all non-white pixels in image),
* in normalized [0,1] coordinates.
@ -75,3 +88,5 @@ class OKULAR_EXPORT Utils
}
#endif
/* kate: replace-tabs on; indent-width 4; */

@ -425,7 +425,6 @@ PDFGenerator::PDFGenerator( QObject *parent, const QVariantList &args )
: Generator( parent, args ), pdfdoc( 0 ),
docInfoDirty( true ), docSynopsisDirty( true ),
docEmbeddedFilesDirty( true ), nextFontPage( 0 ),
dpiX( 72.0 /*Okular::Utils::dpiX()*/ ), dpiY( 72.0 /*Okular::Utils::dpiY()*/ ),
annotProxy( 0 ), synctex_scanner( 0 )
{
setFeature( Threaded );
@ -627,8 +626,8 @@ void PDFGenerator::loadPages(QVector<Okular::Page*> &pagesVector, int rotation,
if (p)
{
const QSizeF pSize = p->pageSizeF();
w = pSize.width() / 72.0 * dpiX;
h = pSize.height() / 72.0 * dpiY;
w = pSize.width() / 72.0 * dpi().width();
h = pSize.height() / 72.0 * dpi().height();
Okular::Rotation orientation = Okular::Rotation0;
switch (p->orientation())
{
@ -908,8 +907,8 @@ QImage PDFGenerator::image( Okular::PixmapRequest * request )
if ( page->rotation() % 2 )
qSwap( pageWidth, pageHeight );
double fakeDpiX = request->width() * dpiX / pageWidth,
fakeDpiY = request->height() * dpiY / pageHeight;
qreal fakeDpiX = request->width() / pageWidth * dpi().width();
qreal fakeDpiY = request->height() / pageHeight * dpi().height();
// generate links rects only the first time
bool genObjectRects = !rectsGenerated.at( page->number() );
@ -1759,8 +1758,8 @@ void PDFGenerator::loadPdfSync( const QString & filePath, QVector<Okular::Page*>
// magic numbers for TeX's RSU's (Ridiculously Small Units) conversion to pixels
Okular::NormalizedPoint p(
( pt.x * dpiX ) / ( 72.27 * 65536.0 * pagesVector[pt.page]->width() ),
( pt.y * dpiY ) / ( 72.27 * 65536.0 * pagesVector[pt.page]->height() )
( pt.x * dpi().width() ) / ( 72.27 * 65536.0 * pagesVector[pt.page]->width() ),
( pt.y * dpi().height() ) / ( 72.27 * 65536.0 * pagesVector[pt.page]->height() )
);
QString file = pt.file;
Okular::SourceReference * sourceRef = new Okular::SourceReference( file, pt.row, pt.column );
@ -1781,7 +1780,7 @@ const Okular::SourceReference * PDFGenerator::dynamicSourceReference( int pageNr
if ( !synctex_scanner )
return 0;
if (synctex_edit_query(synctex_scanner, pageNr + 1, absX * 72. / dpiX, absY * 72. / dpiY) > 0)
if (synctex_edit_query(synctex_scanner, pageNr + 1, absX * 72. / dpi().width(), absY * 72. / dpi().height()) > 0)
{
synctex_node_t node;
// TODO what should we do if there is really more than one node?
@ -1852,8 +1851,8 @@ void PDFGenerator::fillViewportFromSourceReference( Okular::DocumentViewport & v
if ( !viewport.isValid() ) return;
// TeX small points ...
double px = (synctex_node_visible_h( node ) * dpiX) / 72.27;
double py = (synctex_node_visible_v( node ) * dpiY) / 72.27;
double px = (synctex_node_visible_h( node ) * dpi().width()) / 72.27;
double py = (synctex_node_visible_v( node ) * dpi().height()) / 72.27;
viewport.rePos.normalizedX = px / document()->page(viewport.pageNumber)->width();
viewport.rePos.normalizedY = ( py + 0.5 ) / document()->page(viewport.pageNumber)->height();
viewport.rePos.enabled = true;

@ -68,7 +68,7 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, p
const Okular::DocumentSynopsis * generateDocumentSynopsis();
Okular::FontInfo::List fontsForPage( int page );
const QList<Okular::EmbeddedFile*> * embeddedFiles() const;
PageSizeMetric pagesSizeMetric() const { return Points; }
PageSizeMetric pagesSizeMetric() const { return Pixels; }
// [INHERITED] document information
bool isAllowed( Okular::Permission permission ) const;
@ -144,8 +144,6 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, p
mutable bool docEmbeddedFilesDirty;
mutable QList<Okular::EmbeddedFile*> docEmbeddedFiles;
int nextFontPage;
double dpiX;
double dpiY;
PopplerAnnotationProxy *annotProxy;
QHash<Okular::Annotation*, Poppler::Annotation*> annotationsHash;

Loading…
Cancel
Save