Introduce the concept of pixel ratio: the ratio of physical and device independent pixels.
This is useful for rendering of content on Retina-displays of Mac hardware with high resolution.
Qt has real support for this starting with Qt5 - therefore it has to be compiled conditionally.
This change uses some work of Marcelo Galvão Póvoa, thank you.
*/
class Painter {
public:
- Painter() : drawing_enabled_(true) {}
+ Painter(double pixel_ratio) : drawing_enabled_(true), pixel_ratio_(pixel_ratio) {}
static const float thin_line;
/// Indicate wether real screen drawing shall be done or not.
bool isDrawingEnabled() const { return drawing_enabled_; }
+ double pixelRatio() const { return pixel_ratio_; }
+
/// draw a char at position x, y (y is the baseline)
/**
* \return the width of the drawn text.
private:
///
bool drawing_enabled_;
+ /// Ratio between physical pixels and device-independent pixels
+ double pixel_ratio_;
};
} // namespace frontend
#include "ColorCache.h"
#include "ColorSet.h"
#include "GuiClipboard.h"
-#include "GuiImage.h"
#include "GuiKeySymbol.h"
#include "GuiSelection.h"
#include "GuiView.h"
}
+double GuiApplication::pixelRatio() const
+{
+#if QT_VERSION > 0x050000
+ return devicePixelRatio();
+#else
+ return 1.0;
+#endif
+}
+
+
void GuiApplication::clearSession()
{
QSettings settings;
void unregisterView(GuiView * gv);
///
GuiView & view(int id) const;
- ///
+
+ /// Current ratio between physical pixels and device-independent pixels
+ double pixelRatio() const;
+
void processKeySym(KeySymbol const & key, KeyModifier state);
/// return the status bar state string
docstring viewStatusMessage();
const float Painter::thin_line = 0.0;
-GuiPainter::GuiPainter(QPaintDevice * device)
- : QPainter(device), Painter(),
+GuiPainter::GuiPainter(QPaintDevice * device, double pixel_ratio)
+ : QPainter(device), Painter(pixel_ratio),
use_pixmap_cache_(lyxrc.use_pixmap_cache && USE_PIXMAP_CACHE)
{
// new QPainter has default QPen:
if (!isDrawingEnabled())
return;
- drawImage(x, y, qlimage.image(), 0, 0, w, h);
+ QImage const image = qlimage.image();
+ QRectF const drect = QRectF(x, y, w, h);
+ QRectF const srect = QRectF(0, 0, image.width(), image.height());
+ drawImage(drect, image, srect);
}
int const mD = fm.maxDescent();
int const h = mA + mD;
if (w > 0 && h > 0) {
- pm = QPixmap(w, h);
+ pm = QPixmap(pixelRatio() * w , pixelRatio() * h);
+#if QT_VERSION > 0x050000
+ pm.setDevicePixelRatio(pixelRatio());
+#endif
pm.fill(Qt::transparent);
- GuiPainter p(&pm);
+ GuiPainter p(&pm, pixelRatio());
p.setQPainterPen(computeColor(f.realColor()));
if (p.font() != ff)
p.setFont(ff);
namespace frontend {
/**
- * GuiPainter - a painter implementation for Qt4
+ * GuiPainter - a painter implementation for Qt
*/
class GuiPainter : public QPainter, public Painter {
public:
- GuiPainter(QPaintDevice *);
+ GuiPainter(QPaintDevice *, double pixel_ratio);
virtual ~GuiPainter();
/// draw a line from point to point
void paintEvent(QPaintEvent *)
{
- int x = (width() - splash_.width()) / 2;
- int y = (height() - splash_.height()) / 2;
+ QRectF r = splash_.rect();
+#if QT_VERSION > 0x050000
+ r.setWidth(r.width() / splash_.devicePixelRatio());
+ r.setHeight(r.height() / splash_.devicePixelRatio());
+#endif
+ int x = (width() - r.width()) / 2;
+ int y = (height() - r.height()) / 2;
QPainter pain(this);
pain.drawPixmap(x, y, splash_);
}
}
+double GuiView::pixelRatio() const
+{
+#if QT_VERSION > 0x050000
+ return devicePixelRatio();
+#else
+ return 1.0;
+#endif
+}
+
+
GuiWorkArea * GuiView::workArea(int index)
{
if (TabWorkArea * twa = d.currentTabWorkArea())
GuiWorkArea const * currentMainWorkArea() const;
/// return the current document WorkArea (it may not have the focus).
GuiWorkArea * currentMainWorkArea();
+
+ /// Current ratio between physical pixels and device-independent pixels
+ double pixelRatio() const;
Q_SIGNALS:
void closing(int);
GuiWorkArea::Private::Private(GuiWorkArea * parent)
: p(parent), screen_(0), buffer_view_(0), lyx_view_(0), cursor_visible_(false),
need_resize_(false), schedule_redraw_(false), preedit_lines_(1),
+pixel_ratio_(1.0),
completer_(new GuiCompleter(p, p))
{
}
}
+double GuiWorkArea::pixelRatio() const
+{
+#if QT_VERSION > 0x050000
+ return devicePixelRatio();
+#else
+ return 1.0;
+#endif
+}
+
+
void GuiWorkArea::init()
{
// Setup the signals
void GuiWorkArea::paintEvent(QPaintEvent * ev)
{
- QRect const rc = ev->rect();
+ QRectF const rc = ev->rect();
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
- if (d->need_resize_) {
+ if (d->needResize()) {
d->resetScreen();
d->resizeBufferView();
if (d->cursor_visible_) {
}
QPainter pain(viewport());
+ double const pr = pixelRatio();
+ QRectF const rcs = QRectF(rc.x() * pr, rc.y() * pr, rc.width() * pr, rc.height() * pr);
+
if (lyxrc.use_qimage) {
- pain.drawImage(rc, static_cast<QImage const &>(*d->screen_), rc);
+ QImage const & image = static_cast<QImage const &>(*d->screen_);
+ pain.drawImage(rc, image, rcs);
} else {
- pain.drawPixmap(rc, static_cast<QPixmap const &>(*d->screen_), rc);
+ QPixmap const & pixmap = static_cast<QPixmap const &>(*d->screen_);
+ pain.drawPixmap(rc, pixmap, rcs);
}
d->cursor_->draw(pain);
ev->accept();
void GuiWorkArea::Private::updateScreen()
{
- GuiPainter pain(screen_);
+ GuiPainter pain(screen_, p->pixelRatio());
buffer_view_->draw(pain);
}
return;
}
- GuiPainter pain(d->screen_);
+ GuiPainter pain(d->screen_, pixelRatio());
d->buffer_view_->updateMetrics();
d->buffer_view_->draw(pain);
FontInfo font = d->buffer_view_->cursor().getFont().fontInfo();
GuiView const & view() const;
GuiView & view();
+ /// Current ratio between physical pixels and device-independent pixels
+ double pixelRatio() const;
+
public Q_SLOTS:
///
void stopBlinkingCursor();
///
void setCursorShape(Qt::CursorShape shape);
+ bool needResize() const {
+ return need_resize_ || p->pixelRatio() != pixel_ratio_;
+ }
+
void resetScreen()
{
delete screen_;
+ pixel_ratio_ = p->pixelRatio();
if (lyxrc.use_qimage) {
- screen_ = new QImage(p->viewport()->width(), p->viewport()->height(),
- QImage::Format_ARGB32_Premultiplied);
+ QImage *x = new QImage(pixel_ratio_ * p->viewport()->width(),
+ pixel_ratio_ * p->viewport()->height(), QImage::Format_ARGB32_Premultiplied);
+#if QT_VERSION > 0x050000
+ x->setDevicePixelRatio(pixel_ratio_);
+#endif
+ screen_ = x;
} else {
- screen_ = new QPixmap(p->viewport()->width(), p->viewport()->height());
+ QPixmap *x = new QPixmap(pixel_ratio_ * p->viewport()->width(),
+ pixel_ratio_ * p->viewport()->height());
+#if QT_VERSION > 0x050000
+ x->setDevicePixelRatio(pixel_ratio_);
+#endif
+ screen_ = x;
}
}
///
bool schedule_redraw_;
///
int preedit_lines_;
-
+ /// Ratio between physical pixels and device-independent pixels
+ /// We save the last used value to detect changes of the
+ /// current pixel_ratio of the viewport.
+ double pixel_ratio_;
///
GuiCompleter * completer_;