From 9135dcee0743538db730cd05b3daff029d50119f Mon Sep 17 00:00:00 2001 From: Stephan Witt Date: Sun, 12 Oct 2014 19:23:13 +0200 Subject: [PATCH] =?utf8?q?#9130=20Text=20in=20main=20work=20area=20isn't?= =?utf8?q?=20rendered=20with=20high=20resolution=20Introduce=20the=20conce?= =?utf8?q?pt=20of=20pixel=20ratio:=20the=20ratio=20of=20physical=20and=20d?= =?utf8?q?evice=20independent=20pixels.=20This=20is=20useful=20for=20rende?= =?utf8?q?ring=20of=20content=20on=20Retina-displays=20of=20Mac=20hardware?= =?utf8?q?=20with=20high=20resolution.=20Qt=20has=20real=20support=20for?= =?utf8?q?=20this=20starting=20with=20Qt5=20-=20therefore=20it=20has=20to?= =?utf8?q?=20be=20compiled=20conditionally.=20This=20change=20uses=20some?= =?utf8?q?=20work=20of=20Marcelo=20Galv=C3=A3o=20P=C3=B3voa,=20thank=20you?= =?utf8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/frontends/Painter.h | 6 +++++- src/frontends/qt4/GuiApplication.cpp | 11 +++++++++- src/frontends/qt4/GuiApplication.h | 5 ++++- src/frontends/qt4/GuiPainter.cpp | 16 +++++++++----- src/frontends/qt4/GuiPainter.h | 4 ++-- src/frontends/qt4/GuiView.cpp | 19 +++++++++++++++-- src/frontends/qt4/GuiView.h | 3 +++ src/frontends/qt4/GuiWorkArea.cpp | 28 +++++++++++++++++++------ src/frontends/qt4/GuiWorkArea.h | 3 +++ src/frontends/qt4/GuiWorkArea_Private.h | 25 ++++++++++++++++++---- 10 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/frontends/Painter.h b/src/frontends/Painter.h index 78ec6e5715..221da4ada7 100644 --- a/src/frontends/Painter.h +++ b/src/frontends/Painter.h @@ -54,7 +54,7 @@ namespace frontend { */ class Painter { public: - Painter() : drawing_enabled_(true) {} + Painter(double pixel_ratio) : drawing_enabled_(true), pixel_ratio_(pixel_ratio) {} static const float thin_line; @@ -134,6 +134,8 @@ public: /// 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. @@ -170,6 +172,8 @@ public: private: /// bool drawing_enabled_; + /// Ratio between physical pixels and device-independent pixels + double pixel_ratio_; }; } // namespace frontend diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index d09bcdbb5f..2697abeb61 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -17,7 +17,6 @@ #include "ColorCache.h" #include "ColorSet.h" #include "GuiClipboard.h" -#include "GuiImage.h" #include "GuiKeySymbol.h" #include "GuiSelection.h" #include "GuiView.h" @@ -1039,6 +1038,16 @@ GuiApplication * theGuiApp() } +double GuiApplication::pixelRatio() const +{ +#if QT_VERSION > 0x050000 + return devicePixelRatio(); +#else + return 1.0; +#endif +} + + void GuiApplication::clearSession() { QSettings settings; diff --git a/src/frontends/qt4/GuiApplication.h b/src/frontends/qt4/GuiApplication.h index 5e4cda2e8c..410ccc4426 100644 --- a/src/frontends/qt4/GuiApplication.h +++ b/src/frontends/qt4/GuiApplication.h @@ -139,7 +139,10 @@ public: 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(); diff --git a/src/frontends/qt4/GuiPainter.cpp b/src/frontends/qt4/GuiPainter.cpp index c7d56c8b71..986ac4672a 100644 --- a/src/frontends/qt4/GuiPainter.cpp +++ b/src/frontends/qt4/GuiPainter.cpp @@ -52,8 +52,8 @@ namespace frontend { 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: @@ -270,7 +270,10 @@ void GuiPainter::image(int x, int y, int w, int h, graphics::Image const & i) 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); } @@ -367,9 +370,12 @@ int GuiPainter::text(int x, int y, docstring const & s, 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); diff --git a/src/frontends/qt4/GuiPainter.h b/src/frontends/qt4/GuiPainter.h index 3af51750fd..e9c6fdf8b9 100644 --- a/src/frontends/qt4/GuiPainter.h +++ b/src/frontends/qt4/GuiPainter.h @@ -29,11 +29,11 @@ class FontInfo; 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 diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index cba88ee21d..8c5080763f 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -172,8 +172,13 @@ public: 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_); } @@ -1204,6 +1209,16 @@ void GuiView::setBusy(bool busy) } +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()) diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h index 9b7ee2e953..b10548d89e 100644 --- a/src/frontends/qt4/GuiView.h +++ b/src/frontends/qt4/GuiView.h @@ -199,6 +199,9 @@ public: 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); diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index e5b2cf57c9..fbc2eca088 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -246,6 +246,7 @@ SyntheticMouseEvent::SyntheticMouseEvent() 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)) { } @@ -266,6 +267,16 @@ GuiWorkArea::GuiWorkArea(Buffer & buffer, GuiView & gv) } +double GuiWorkArea::pixelRatio() const +{ +#if QT_VERSION > 0x050000 + return devicePixelRatio(); +#else + return 1.0; +#endif +} + + void GuiWorkArea::init() { // Setup the signals @@ -1120,11 +1131,11 @@ void GuiWorkArea::Private::update(int x, int y, int w, int h) 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_) { @@ -1134,10 +1145,15 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev) } 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(*d->screen_), rc); + QImage const & image = static_cast(*d->screen_); + pain.drawImage(rc, image, rcs); } else { - pain.drawPixmap(rc, static_cast(*d->screen_), rc); + QPixmap const & pixmap = static_cast(*d->screen_); + pain.drawPixmap(rc, pixmap, rcs); } d->cursor_->draw(pain); ev->accept(); @@ -1146,7 +1162,7 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev) void GuiWorkArea::Private::updateScreen() { - GuiPainter pain(screen_); + GuiPainter pain(screen_, p->pixelRatio()); buffer_view_->draw(pain); } @@ -1220,7 +1236,7 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e) 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(); diff --git a/src/frontends/qt4/GuiWorkArea.h b/src/frontends/qt4/GuiWorkArea.h index e5c488f6a8..fb6341b1a0 100644 --- a/src/frontends/qt4/GuiWorkArea.h +++ b/src/frontends/qt4/GuiWorkArea.h @@ -84,6 +84,9 @@ public: GuiView const & view() const; GuiView & view(); + /// Current ratio between physical pixels and device-independent pixels + double pixelRatio() const; + public Q_SLOTS: /// void stopBlinkingCursor(); diff --git a/src/frontends/qt4/GuiWorkArea_Private.h b/src/frontends/qt4/GuiWorkArea_Private.h index 6d180dd175..0915b64d4c 100644 --- a/src/frontends/qt4/GuiWorkArea_Private.h +++ b/src/frontends/qt4/GuiWorkArea_Private.h @@ -117,14 +117,28 @@ struct GuiWorkArea::Private /// 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; } } /// @@ -155,7 +169,10 @@ struct GuiWorkArea::Private 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_; -- 2.39.2