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_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_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(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS) add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories( include_directories(
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${KDE4_INCLUDES} ${KDE4_INCLUDES}
${QIMAGEBLITZ_INCLUDES} ${QIMAGEBLITZ_INCLUDES}
${LibKScreen_INCLUDE_DIR}
) )
add_subdirectory( active ) 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} ) 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 ) set_target_properties(okularcore PROPERTIES VERSION 3.0.0 SOVERSION 3 )
install(TARGETS okularcore ${INSTALL_TARGETS_DEFAULT_ARGS} ) install(TARGETS okularcore ${INSTALL_TARGETS_DEFAULT_ARGS} )

@ -1,2 +1,5 @@
/* Defines if force the use DRM in okular */ /* Defines if force the use DRM in okular */
#define OKULAR_FORCE_DRM ${_OKULAR_FORCE_DRM} #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.h"
#include "view_p.h" #include "view_p.h"
#include "form.h" #include "form.h"
#include "utils.h"
#include <memory> #include <memory>
@ -267,6 +268,14 @@ QString DocumentPrivate::localizedSize(const QSizeF &size) const
inchesHeight = size.height() / 72.0; inchesHeight = size.height() / 72.0;
break; break;
case Generator::Pixels:
{
const QSizeF dpi = m_generator->dpi();
inchesWidth = size.width() / dpi.width();
inchesHeight = size.height() / dpi.height();
}
break;
case Generator::None: case Generator::None:
break; 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)) ); QObject::connect( m_generator, SIGNAL(notice(QString,int)), m_parent, SIGNAL(notice(QString,int)) );
QApplication::setOverrideCursor( Qt::WaitCursor ); QApplication::setOverrideCursor( Qt::WaitCursor );
m_generator->setDPI(Utils::realDpi(m_widget));
bool openOk = false; bool openOk = false;
if ( !isstdin ) if ( !isstdin )
{ {

@ -31,7 +31,8 @@ GeneratorPrivate::GeneratorPrivate()
: m_document( 0 ), : m_document( 0 ),
mPixmapGenerationThread( 0 ), mTextPageGenerationThread( 0 ), mPixmapGenerationThread( 0 ), mTextPageGenerationThread( 0 ),
m_mutex( 0 ), m_threadsMutex( 0 ), mPixmapReady( true ), mTextPageReady( true ), 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; 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 ) PixmapRequest::PixmapRequest( DocumentObserver *observer, int pageNumber, int width, int height, int priority, PixmapRequestFeatures features )
: d( new PixmapRequestPrivate ) : d( new PixmapRequestPrivate )
{ {

@ -20,6 +20,7 @@
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QSharedDataPointer> #include <QtCore/QSharedDataPointer>
#include <QtCore/QSizeF>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtCore/QVector> #include <QtCore/QVector>
@ -308,7 +309,8 @@ class OKULAR_EXPORT Generator : public QObject
enum PageSizeMetric enum PageSizeMetric
{ {
None, ///< The page size is not defined in a physical metric. 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; bool hasFeature( GeneratorFeature feature ) const;
/**
* Update DPI of the generator
*
* @since 0.19 (KDE 4.13)
*/
void setDPI(const QSizeF &dpi);
Q_SIGNALS: Q_SIGNALS:
/** /**
* This signal should be emitted whenever an error occurred in the generator. * 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 ); 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: protected Q_SLOTS:
/** /**
* Gets the font data for the given font * Gets the font data for the given font

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

@ -18,7 +18,11 @@
#include <QIODevice> #include <QIODevice>
#ifdef Q_WS_X11 #ifdef Q_WS_X11
#include <QX11Info> #include "config-okular.h"
#if HAVE_LIBKSCREEN
#include <kscreen/config.h>
#endif
#include <QX11Info>
#endif #endif
#ifdef Q_WS_MAC #ifdef Q_WS_MAC
@ -81,6 +85,48 @@ double Utils::realDpiY()
return (double(w->height()) * 25.4) / double(w->heightMM()); 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) #elif defined(Q_WS_MAC)
/* /*
* Code copied from http://developer.apple.com/qa/qa2001/qa1217.html * Code copied from http://developer.apple.com/qa/qa2001/qa1217.html
@ -164,6 +210,11 @@ double Utils::realDpiY()
{ {
return dpiY(); return dpiY();
} }
QSizeF Utils::realDpi(QWidget*)
{
return QSizeF(realDpiX(), realDpiY());
}
#else #else
double Utils::dpiX() double Utils::dpiX()
@ -185,6 +236,11 @@ double Utils::realDpiY()
{ {
return dpiY(); return dpiY();
} }
QSizeF Utils::realDpi(QWidget*)
{
return QSizeF(realDpiX(), realDpiY());
}
#endif #endif
inline static bool isWhite( QRgb argb ) { inline static bool isWhite( QRgb argb ) {

@ -15,6 +15,7 @@
class QRect; class QRect;
class QImage; class QImage;
class QWidget;
namespace Okular namespace Okular
{ {
@ -50,6 +51,7 @@ class OKULAR_EXPORT Utils
* setting. Otherwise, returns the same as dpiX(), * setting. Otherwise, returns the same as dpiX(),
* *
* @since 0.9 (KDE 4.3) * @since 0.9 (KDE 4.3)
* @deprecated Can not work with multi-monitor configurations
*/ */
static double realDpiX(); static double realDpiX();
@ -60,9 +62,20 @@ class OKULAR_EXPORT Utils
* setting. Otherwise, returns the same as dpiX(), * setting. Otherwise, returns the same as dpiX(),
* *
* @since 0.9 (KDE 4.3) * @since 0.9 (KDE 4.3)
* @deprecated Can not work with multi-monitor configurations
*/ */
static double realDpiY(); 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), * Compute the smallest rectangle that contains all non-white pixels in image),
* in normalized [0,1] coordinates. * in normalized [0,1] coordinates.
@ -75,3 +88,5 @@ class OKULAR_EXPORT Utils
} }
#endif #endif
/* kate: replace-tabs on; indent-width 4; */

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

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

Loading…
Cancel
Save