View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0014004 | Scribus | Canvas | public | 2016-05-01 02:00 | 2016-05-16 22:21 |
Reporter | Assigned To | cbradney | |||
Priority | normal | Severity | feature | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 1.5.2.svn | ||||
Target Version | 1.5.2 | Fixed in Version | 1.5.2.svn | ||
Summary | 0014004: Improve Canvas rendering on Hi-DPI screens | ||||
Description | The attached patch improves the Canvas rendering on Hi-DPI screens making text and other vector drawings look sharp and not fuzzy. Namely: * Set Qt::AA_UseHighDpiPixmaps to allow for Hi-DPI QPixmaps * Multiply the size of the multitude of intermediate QImage’s and QPixmaps we create for the Canvas by its devicePixelFactor, and set their devicePixelFactor as well. * Set the device scale of Cairo surface to that of the QPixmap we are drawing it into. | ||||
Steps To Reproduce | Run Scrinus on a system with a Hi-DPI screen (one might need to set QT_AUTO_SCREEN_SCALE_FACTOR or QT_DEVICE_PIXEL_RATIO depending on Qt version to enable Hi-DPI mode), text and vectors on the Canvas look fuzzy compared to Scribus UI. | ||||
Tags | discussion, HiDPI | ||||
Patch | Yes | ||||
2016-05-01 02:08
|
|
2016-05-01 02:08
|
|
|
I uploaded a new patch fixing few rendering glitches in the first one and less code duplication. |
2016-05-01 15:18
|
0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch (7,740 bytes)
From f9981df2939eadd18223bc5e20af99373db133f1 Mon Sep 17 00:00:00 2001 From: Khaled Hosny <khaledhosny@eglug.org> Date: Sun, 1 May 2016 02:44:10 +0200 Subject: [PATCH] Improve Canvas drawing on Hi-DPI screens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Set Qt::AA_UseHighDpiPixmaps to allow for Hi-DPI QPixmaps * Multiply the size of the multitude of intermediate QImage’s and QPixmaps we create for the Canvas by its devicePixelFactor, and set their devicePixelFactor as well. * Set the device scale of Cairo surface to that of the QPixmap we are drawing it into. --- scribus/canvas.cpp | 46 ++++++++++++++++++++++++++-------------------- scribus/canvas.h | 5 +++++ scribus/scpainter.cpp | 1 + scribus/scribusapp.cpp | 2 +- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/scribus/canvas.cpp b/scribus/canvas.cpp index ab19ccc..2af8452 100644 --- a/scribus/canvas.cpp +++ b/scribus/canvas.cpp @@ -663,7 +663,7 @@ bool Canvas::adjustBuffer() { // qDebug() << "adjust buffer: invalid buffer, viewport" << viewport; m_bufferRect = viewport; - m_buffer = QPixmap(m_bufferRect.width(), m_bufferRect.height()); + m_buffer = createPixmap(m_bufferRect.width(), m_bufferRect.height()); fillBuffer(&m_buffer, m_bufferRect.topLeft(), m_bufferRect); ret = true; #if DRAW_DEBUG_LINES @@ -691,8 +691,7 @@ bool Canvas::adjustBuffer() { // qDebug() << "adjust buffer: fresh buffer" << m_bufferRect << "-->" << newRect; m_bufferRect = newRect; -// m_buffer = QImage(m_bufferRect.width(), m_bufferRect.height(), QImage::Format_ARGB32); - m_buffer = QPixmap(m_bufferRect.width(), m_bufferRect.height()); + m_buffer = createPixmap(m_bufferRect.width(), m_bufferRect.height()); fillBuffer(&m_buffer, m_bufferRect.topLeft(), m_bufferRect); ret = true; #if DRAW_DEBUG_LINES @@ -706,8 +705,7 @@ bool Canvas::adjustBuffer() else { // copy buffer: -// QImage newBuffer(newRect.width(), newRect.height(), QImage::Format_ARGB32); - QPixmap newBuffer(newRect.width(), newRect.height()); + QPixmap newBuffer = createPixmap(newRect.width(), newRect.height()); QPainter p(&newBuffer); int xpos = m_bufferRect.x() - newRect.x(); int ypos = m_bufferRect.y() - newRect.y(); @@ -735,8 +733,8 @@ bool Canvas::adjustBuffer() { height = newRect.height() - ypos; } -// p.drawImage(xpos, ypos, m_buffer, x, y, width + 1, height + 1); // FIXME: == params drawPixmap? - p.drawPixmap(xpos, ypos, m_buffer, x, y, width + 1, height + 1); + + drawPixmap(p, xpos, ypos, m_buffer, x, y, width + 1, height + 1); #if DRAW_DEBUG_LINES p.setPen(Qt::blue); p.drawLine(xpos, ypos+height/2, xpos+width/2, ypos); @@ -818,11 +816,7 @@ void Canvas::paintEvent ( QPaintEvent * p ) #endif // fill buffer if necessary bool bufferFilled = adjustBuffer(); - // It is ugly, but until we figure out why drawing directly on the - // widget is so slow, it saves us a Cray! - pm - QPixmap tmpImg(p->rect().size()); - QPainter qp(&tmpImg); - qp.translate(-p->rect().x(), -p->rect().y()); + QPainter qp(this); switch (m_renderMode) { case RENDER_NORMAL: @@ -850,8 +844,7 @@ void Canvas::paintEvent ( QPaintEvent * p ) int hV = p->rect().height(); if (hV > 0 && wV > 0) { -// qp.drawImage(p->rect().x(), p->rect().y(), m_buffer, xV, yV, wV, hV); - qp.drawPixmap(p->rect().x(), p->rect().y(), m_buffer, xV, yV, wV, hV); + drawPixmap(qp, p->rect().x(), p->rect().y(), m_buffer, xV, yV, wV, hV); #if DRAW_DEBUG_LINES // qDebug() << "normal rendering" << xV << yV << wV << hV << "at" << p->rect().x() << p->rect().y(); qp.setPen(Qt::blue); @@ -904,9 +897,7 @@ void Canvas::paintEvent ( QPaintEvent * p ) #endif if (hV > 0 && wV > 0) { -// qp.drawImage(p->rect().x(), p->rect().y(), m_buffer, xV, yV, wV, hV); - - qp.drawPixmap(p->rect().x(), p->rect().y(), m_buffer, xV, yV, wV, hV); + drawPixmap(qp, p->rect().x(), p->rect().y(), m_buffer, xV, yV, wV, hV); #if DRAW_DEBUG_LINES // qDebug() << "buffered rendering" << xV << yV << wV << hV << "at" << p->rect().x() << p->rect().y(); qp.setPen(Qt::green); @@ -948,8 +939,6 @@ void Canvas::paintEvent ( QPaintEvent * p ) // does mode specific rendering, currently selection in legacymode and nodes in nodeedit m_view->m_canvasMode->drawControls(&qp); m_view->m_canvasMode->drawSnapLine(&qp); - QPainter tp(this); - tp.drawPixmap(p->rect(), tmpImg, tmpImg.rect()); #ifdef SHOW_ME_WHAT_YOU_GET_IN_D_CANVA t6 = t.elapsed(); qDebug()<<dmode<<t1<<t2<<t3<<t4<<t5<<t6<<"-" <<t1+t2+t3+t4+t5+t6; @@ -969,7 +958,8 @@ void Canvas::drawContents(QPainter *psx, int clipx, int clipy, int clipw, int cl // qDebug() << "Canvas::drawContents" << clipx << clipy << clipw << cliph<<m_viewMode.forceRedraw<<m_viewMode.operItemSelecting; uint docPagesCount=m_doc->Pages->count(); ScPainter *painter=0; - QImage img = QImage(clipw, cliph, QImage::Format_ARGB32_Premultiplied); + QImage img = QImage(clipw * devicePixelRatio(), cliph * devicePixelRatio(), QImage::Format_ARGB32_Premultiplied); + img.setDevicePixelRatio(devicePixelRatio()); painter = new ScPainter(&img, img.width(), img.height(), 1.0, 0); painter->clear(palette().color(QPalette::Window)); painter->newPath(); @@ -2411,6 +2401,22 @@ void Canvas::calculateFrameLinkPoints(PageItem *pi1, PageItem *pi2, FPoint & sta end.transform(pi2->xPos(), pi2->yPos(), pi2->rotation(), 1, 1, false); } +QPixmap Canvas::createPixmap(double w, double h) +{ + QPixmap p(w * devicePixelRatio(), h * devicePixelRatio()); + p.setDevicePixelRatio(devicePixelRatio()); + return p; +} + +void Canvas::drawPixmap(QPainter& painter, double x, double y, const QPixmap& pixmap, double sx, double sy, double sw, double sh) +{ + sx *= devicePixelRatio(); + sy *= devicePixelRatio(); + sw *= devicePixelRatio(); + sh *= devicePixelRatio(); + painter.drawPixmap(x, y, pixmap, sx, sy, sw, sh); +} + void Canvas::displayXYHUD(QPoint m) { if (!PrefsManager::instance()->appPrefs.displayPrefs.showMouseCoordinates) diff --git a/scribus/canvas.h b/scribus/canvas.h index 1501532..5aeaf7a 100644 --- a/scribus/canvas.h +++ b/scribus/canvas.h @@ -260,6 +260,11 @@ private: void getLinkedFrames(PageItem* currItem); void getClipPathForPages(FPointArray* PoLine); void calculateFrameLinkPoints(PageItem* pi1, PageItem* pi2, FPoint& start, FPoint& end); + + // create a potentially hidpi pixmap + QPixmap createPixmap(double w, double h); + // draw a potentially hidpi pixmap + void drawPixmap(QPainter &painter, double x, double y, const QPixmap &pixmap, double sx, double sy, double sw, double sh); private: ScribusDoc* m_doc; diff --git a/scribus/scpainter.cpp b/scribus/scpainter.cpp index 7b36813..19cdf15 100644 --- a/scribus/scpainter.cpp +++ b/scribus/scpainter.cpp @@ -52,6 +52,7 @@ ScPainter::ScPainter( QImage *target, unsigned int w, unsigned int h, double tra m_matrix = QTransform(); m_zoomStack.clear(); cairo_surface_t *img = cairo_image_surface_create_for_data(m_image->bits(), CAIRO_FORMAT_ARGB32, w, h, w*4); + cairo_surface_set_device_scale(img, m_image->devicePixelRatio(), m_image->devicePixelRatio()); m_cr = cairo_create(img); cairo_save( m_cr ); cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD); diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp index 486f478..800e1cb 100644 --- a/scribus/scribusapp.cpp +++ b/scribus/scribusapp.cpp @@ -110,7 +110,7 @@ ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv), m_scDLMgr = 0; m_ScCore = NULL; initDLMgr(); - + setAttribute(Qt::AA_UseHighDpiPixmaps, true); } ScribusQApp::~ScribusQApp() -- 2.8.2 |
|
Thanks Khaled! |
|
Looks good, unfortunately I have no HiDPI screen at my disposal, so I'm totally unable to do any test. |
|
On non-Hi-DPI screens nothing should change since deviceScaleFactor() will be 1 then, so I think this is low risk for most of Scribus users. I’d say we apply this and deal with any bugs later, I’m using a Hi-DPI screen myself and should be able to catch any obvious issue. |
|
|
|
Works well on my 3200x1800 13" screen. The objects on the canvas renders blurry before the patch, and sharp after applying it. One issue is that the Scribus logo in the left corner get a lot more padding with this patch for some reason. |
|
I see the padding as well, need to find out how the logo is drawn and investigate. |
|
Seems that the icon is set with QApplication::setWindowIcon(), so that is probably a Qt issue. However I just realised that Scribus is the only application I have that has such an icon, may be it is time to retire this outdated Window icon stuff (but it is a minor issue nevertheless). |
|
Nah, if you don't call QApplication::setWindowIcon(), scribus icon in the taskbar will be incorrect on Windows for eg. |
|
But Scribus is the only Qt application I see having that icon in the toolbar. |
|
andreasn1, can you test Khaled's patch on the latest scribus trunk ? |
Date Modified | Username | Field | Change |
---|---|---|---|
2016-05-01 02:00 |
|
New Issue | |
2016-05-01 02:00 |
|
File Added: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 02:08 |
|
File Added: hidpi-before.png | |
2016-05-01 02:08 |
|
File Added: hidpi-after.png | |
2016-05-01 14:59 |
|
File Deleted: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 14:59 |
|
File Added: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 15:00 |
|
Note Added: 0040679 | |
2016-05-01 15:02 |
|
File Deleted: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 15:02 |
|
File Added: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 15:18 |
|
File Deleted: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 15:18 |
|
File Added: 0001-Improve-Canvas-drawing-on-Hi-DPI-screens.patch | |
2016-05-01 17:26 | Kunda | Note Added: 0040688 | |
2016-05-01 17:31 | Kunda | Tag Attached: HiDPI | |
2016-05-01 19:34 | jghali | Note Added: 0040691 | |
2016-05-01 22:06 |
|
Note Added: 0040692 | |
2016-05-02 14:03 | Kunda | Relationship added | related to 0013204 |
2016-05-04 07:00 | Kunda | Tag Attached: discussion | |
2016-05-04 07:00 | Kunda | Tag Attached: #pending | |
2016-05-14 22:10 | andreasn1 | File Added: Screenshot from 2016-05-14 23-36-19.png | |
2016-05-14 22:11 | andreasn1 | Note Added: 0041060 | |
2016-05-14 22:40 |
|
Note Added: 0041062 | |
2016-05-14 22:58 |
|
Note Added: 0041063 | |
2016-05-15 06:01 | jghali | Note Added: 0041069 | |
2016-05-15 07:48 |
|
Note Added: 0041072 | |
2016-05-15 13:10 | Kunda | Note Added: 0041081 | |
2016-05-15 13:10 | Kunda | Status | new => acknowledged |
2016-05-15 13:21 | Kunda | Tag Attached: #please_test | |
2016-05-15 23:59 | Kunda | Target Version | => 1.5.3 |
2016-05-16 13:39 | cbradney | Status | acknowledged => resolved |
2016-05-16 13:39 | cbradney | Fixed in Version | => 1.5.2.svn |
2016-05-16 13:39 | cbradney | Resolution | open => fixed |
2016-05-16 13:39 | cbradney | Assigned To | => cbradney |
2016-05-16 13:40 | cbradney | Target Version | 1.5.3 => 1.5.2 |
2016-05-16 13:41 | cbradney | Status | resolved => closed |
2016-05-16 16:42 | Kunda | Relationship added | related to 0014023 |
2016-05-16 16:44 | Kunda | Relationship replaced | has duplicate 0014023 |
2016-05-16 17:11 | Kunda | Tag Detached: #pending | |
2016-05-16 17:11 | Kunda | Tag Detached: #please_test |