From a8b40b4153aad87849500855f8c9140ce98f3b77 Mon Sep 17 00:00:00 2001 From: Frederic Devernay Date: Fri, 10 Sep 2021 16:12:53 -0700 Subject: [PATCH] fix OpenGL font issues on HiDPI displays --- Gui/CurveWidget.cpp | 30 +++++++---- Gui/CurveWidgetPrivate.cpp | 24 ++++----- Gui/CurveWidgetPrivate.h | 3 +- Gui/DopeSheetView.cpp | 79 +++++++++++++++-------------- Gui/Histogram.cpp | 101 ++++++++++++++++++++----------------- Gui/ScaleSliderQWidget.cpp | 2 +- Gui/TimeLineGui.cpp | 78 ++++++++++++++++++---------- Gui/ViewerGL.cpp | 58 ++++++++++++--------- Gui/ViewerGL.h | 3 -- Gui/ViewerGLPrivate.cpp | 3 +- Gui/ViewerGLPrivate.h | 3 +- 11 files changed, 216 insertions(+), 168 deletions(-) diff --git a/Gui/CurveWidget.cpp b/Gui/CurveWidget.cpp index 690977c831..d0d22b233d 100644 --- a/Gui/CurveWidget.cpp +++ b/Gui/CurveWidget.cpp @@ -616,6 +616,16 @@ CurveWidget::paintGL() if (_imp->zoomCtx.factor() <= 0) { return; } + + { + double screenPixelRatio = getScreenPixelRatio(); + if (screenPixelRatio != _imp->_screenPixelRatio) { + _imp->_screenPixelRatio = screenPixelRatio; + _imp->_textFont.reset(new QFont(appFont, appFontSize * screenPixelRatio)); + } + } + assert(_imp->_textFont); + double zoomLeft, zoomRight, zoomBottom, zoomTop; zoomLeft = _imp->zoomCtx.left(); zoomRight = _imp->zoomCtx.right(); @@ -625,8 +635,6 @@ CurveWidget::paintGL() double bgR, bgG, bgB; appPTR->getCurrentSettings()->getCurveEditorBGColor(&bgR, &bgG, &bgB); - double screenPixelRatio = getScreenPixelRatio(); - if ( (zoomLeft == zoomRight) || (zoomTop == zoomBottom) ) { glClearColor(bgR, bgG, bgB, 1.); glClear(GL_COLOR_BUFFER_BIT); @@ -664,22 +672,22 @@ CurveWidget::paintGL() glCheckErrorIgnoreOSXBug(); } - _imp->drawScale(screenPixelRatio); + _imp->drawScale(_imp->_screenPixelRatio); if (_imp->_timelineEnabled) { - _imp->drawTimelineMarkers(screenPixelRatio); + _imp->drawTimelineMarkers(_imp->_screenPixelRatio); } if (_imp->_drawSelectedKeyFramesBbox) { - _imp->drawSelectedKeyFramesBbox(screenPixelRatio); + _imp->drawSelectedKeyFramesBbox(_imp->_screenPixelRatio); } - _imp->drawCurves(screenPixelRatio); + _imp->drawCurves(_imp->_screenPixelRatio); if ( !_imp->_selectionRectangle.isNull() ) { - _imp->drawSelectionRectangle(screenPixelRatio); + _imp->drawSelectionRectangle(_imp->_screenPixelRatio); } } // GLProtectAttrib a(GL_TRANSFORM_BIT | GL_COLOR_BUFFER_BIT); glCheckError(); @@ -727,8 +735,8 @@ CurveWidget::renderText(double x, if ( (w <= 0) || (h <= 0) || (right <= left) || (top <= bottom) ) { return; } - double scalex = (right - left) / w; - double scaley = (top - bottom) / h; + double scalex = (right - left) / (w * _imp->_screenPixelRatio); + double scaley = (top - bottom) / (h * _imp->_screenPixelRatio); _imp->textRenderer.renderText(x, y, scalex, scaley, text, color, font, flags); glCheckError(); } @@ -2006,7 +2014,7 @@ CurveWidget::getFont() const // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); - return *_imp->_font; + return *_imp->_textFont; } const SelectedKeys & @@ -2024,7 +2032,7 @@ CurveWidget::getTextFont() const // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); - return *_imp->_font; + return *_imp->_textFont; } void diff --git a/Gui/CurveWidgetPrivate.cpp b/Gui/CurveWidgetPrivate.cpp index 3ae6507fdb..38f194b45a 100644 --- a/Gui/CurveWidgetPrivate.cpp +++ b/Gui/CurveWidgetPrivate.cpp @@ -76,7 +76,8 @@ CurveWidgetPrivate::CurveWidgetPrivate(Gui* gui, , _selectedCurveColor(255, 255, 89, 255) , _nextCurveAddedColor() , textRenderer() - , _font( new QFont(appFont, appFontSize) ) + , _screenPixelRatio(0.) + , _textFont() , _curves() , _selectedKeyFrames() , _mustSetDragOrientation(false) @@ -116,7 +117,6 @@ CurveWidgetPrivate::~CurveWidgetPrivate() // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); - delete _font; _curves.clear(); } @@ -454,7 +454,7 @@ CurveWidgetPrivate::drawScale(double screenPixelRatio) return; } - QFontMetrics fontM(*_font); + QFontMetrics fm(*_textFont); const double smallestTickSizePixel = 10.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 500.; // tick size (in pixels) for alpha = 1. double gridR, gridG, gridB; @@ -492,7 +492,7 @@ CurveWidgetPrivate::drawScale(double screenPixelRatio) ticks_fill(half_tick, ticks_max, m1, m2, &ticks); const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; - const double minTickSizeTextPixel = (axis == 0) ? fontM.width( QLatin1String("00") ) : fontM.height(); // AXIS-SPECIFIC + const double minTickSizeTextPixel = ( (axis == 0) ? fm.width( QLatin1String("00") ) : fm.height() ) / _screenPixelRatio; // AXIS-SPECIFIC const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; for (int i = m1; i <= m2; ++i) { double value = i * smallTickSize + offset; @@ -517,22 +517,22 @@ CurveWidgetPrivate::drawScale(double screenPixelRatio) if (tickSize > minTickSizeText) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = QString::number(value); - const int sSizePixel = (axis == 0) ? fontM.width(s) : fontM.height(); // AXIS-SPECIFIC + const double sSizePixel = ( (axis == 0) ? fm.width(s) : fm.height() ) / _screenPixelRatio; // AXIS-SPECIFIC if (tickSizePixel > sSizePixel) { - const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; + const double sSizeFullPixel = sSizePixel + minTickSizeTextPixel; double alphaText = 1.0; //alpha; if (tickSizePixel < sSizeFullPixel) { // when the text size is between sSizePixel and sSizeFullPixel, // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } - alphaText = std::min(alphaText, alpha); // don't draw more opaque than tcks + //alphaText = std::min(alphaText, alpha); // don't draw more opaque than ticks QColor c = scaleColor; c.setAlpha(255 * alphaText); if (axis == 0) { - _widget->renderText(value, btmLeft.y(), s, c, *_font, Qt::AlignHCenter); // AXIS-SPECIFIC + _widget->renderText(value, btmLeft.y(), s, c, *_textFont, Qt::AlignHCenter); // AXIS-SPECIFIC } else { - _widget->renderText(btmLeft.x(), value, s, c, *_font, Qt::AlignVCenter); // AXIS-SPECIFIC + _widget->renderText(btmLeft.x(), value, s, c, *_textFont, Qt::AlignVCenter); // AXIS-SPECIFIC } } } @@ -771,7 +771,7 @@ CurveWidgetPrivate::isNearbyKeyFrameText(const QPoint& pt) const topLeftWidget.ry() += yOffset; QString coordStr = QString::fromUtf8("x: %1, y: %2").arg( (*it2)->key.getTime() ).arg( (*it2)->key.getValue() ); - QPointF btmRightWidget( topLeftWidget.x() + fm.width(coordStr), topLeftWidget.y() + fm.height() ); + QPointF btmRightWidget( topLeftWidget.x() + fm.width(coordStr) / _screenPixelRatio, topLeftWidget.y() + fm.height() / _screenPixelRatio ); if ( (pt.x() >= topLeftWidget.x() - CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) && (pt.x() <= btmRightWidget.x() + CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) && ( pt.y() >= topLeftWidget.y() - CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) && ( pt.y() <= btmRightWidget.y() + CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) ) { @@ -836,8 +836,8 @@ CurveWidgetPrivate::isNearbySelectedTangentText(const QPoint & pt) const QString leftCoordStr = QString( tr("l: %1") ).arg(std::floor( ( (*it2)->key.getLeftDerivative() * rounding ) + 0.5 ) / rounding); QString rightCoordStr = QString( tr("r: %1") ).arg(std::floor( ( (*it2)->key.getRightDerivative() * rounding ) + 0.5 ) / rounding); - QPointF btmRight_LeftTanWidget( topLeft_LeftTanWidget.x() + fm.width(leftCoordStr), topLeft_LeftTanWidget.y() + fm.height() ); - QPointF btmRight_RightTanWidget( topLeft_RightTanWidget.x() + fm.width(rightCoordStr), topLeft_RightTanWidget.y() + fm.height() ); + QPointF btmRight_LeftTanWidget( topLeft_LeftTanWidget.x() + fm.width(leftCoordStr) / _screenPixelRatio, topLeft_LeftTanWidget.y() + fm.height() / _screenPixelRatio ); + QPointF btmRight_RightTanWidget( topLeft_RightTanWidget.x() + fm.width(rightCoordStr) / _screenPixelRatio, topLeft_RightTanWidget.y() + fm.height() / _screenPixelRatio ); if ( (pt.x() >= topLeft_LeftTanWidget.x() - CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) && (pt.x() <= btmRight_LeftTanWidget.x() + CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) && ( pt.y() >= topLeft_LeftTanWidget.y() - CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) && ( pt.y() <= btmRight_LeftTanWidget.y() + CLICK_DISTANCE_FROM_CURVE_ACCEPTANCE) ) { diff --git a/Gui/CurveWidgetPrivate.h b/Gui/CurveWidgetPrivate.h index 46854e0c28..62cc3b5693 100644 --- a/Gui/CurveWidgetPrivate.h +++ b/Gui/CurveWidgetPrivate.h @@ -161,7 +161,8 @@ class CurveWidgetPrivate QColor _selectedCurveColor; QColor _nextCurveAddedColor; TextRenderer textRenderer; - QFont* _font; + double _screenPixelRatio; + boost::scoped_ptr _textFont; Curves _curves; SelectedKeys _selectedKeyFrames; bool _mustSetDragOrientation; diff --git a/Gui/DopeSheetView.cpp b/Gui/DopeSheetView.cpp index 0203c58ac1..bd9c9bd0ca 100644 --- a/Gui/DopeSheetView.cpp +++ b/Gui/DopeSheetView.cpp @@ -278,7 +278,8 @@ class DopeSheetViewPrivate int rangeComputationRecursion; // for rendering - QFont *font; + double _screenPixelRatio; + boost::scoped_ptr _textFont; TextRenderer textRenderer; // for textures @@ -322,7 +323,8 @@ DopeSheetViewPrivate::DopeSheetViewPrivate(DopeSheetView *qq) , nodeRanges() , nodeRangesBeingComputed() , rangeComputationRecursion(0) - , font( new QFont(appFont, appFontSize) ) + , _screenPixelRatio(0) + , _textFont() , textRenderer() , kfTexturesIDs() , zoomContext(0.01, 100.) @@ -872,7 +874,7 @@ DopeSheetViewPrivate::drawScale() const return; } - QFontMetrics fontM(*font); + QFontMetrics fm(*_textFont); const double smallestTickSizePixel = 5.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 1000.; // tick size (in pixels) for alpha = 1. @@ -886,8 +888,6 @@ DopeSheetViewPrivate::drawScale() const Image::clamp(scaleG, 0., 1.), Image::clamp(scaleB, 0., 1.) ); - double screenPixelRatio = q_ptr->getScreenPixelRatio(); - // Perform drawing { GLProtectAttrib a(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); @@ -918,7 +918,7 @@ DopeSheetViewPrivate::drawScale() const const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; - const double minTickSizeTextPixel = fontM.width( QString::fromUtf8("00") ); + const double minTickSizeTextPixel = fm.width( QString::fromUtf8("00") ) / _screenPixelRatio; const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; glCheckError(); @@ -931,7 +931,7 @@ DopeSheetViewPrivate::drawScale() const glColor4f(scaleColor.redF(), scaleColor.greenF(), scaleColor.blueF(), alpha); // Draw the vertical lines belonging to the grid - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); glVertex2f( value, bottomLeft.y() ); glVertex2f( value, topRight.y() ); @@ -943,7 +943,7 @@ DopeSheetViewPrivate::drawScale() const if (tickSize > minTickSizeText) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = QString::number(value); - const int sSizePixel = fontM.width(s); + const int sSizePixel = fm.width(s) / _screenPixelRatio; if (tickSizePixel > sSizePixel) { const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; @@ -958,7 +958,7 @@ DopeSheetViewPrivate::drawScale() const QColor c = scaleColor; c.setAlpha(255 * alphaText); - renderText(value, bottomLeft.y(), s, c, *font, Qt::AlignHCenter); + renderText(value, bottomLeft.y(), s, c, *_textFont, Qt::AlignHCenter); // Uncomment the line below to draw the indicator on top too // parent->renderText(value, topRight.y() - 20, s, c, *font); @@ -1113,10 +1113,9 @@ DopeSheetViewPrivate::drawNodeRowSeparation(const DSNodePtr dsNode) const GLProtectAttrib a(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT); QRectF nameItemRect = hierarchyView->visualItemRect( dsNode->getTreeItem() ); QRectF rowRect = nameItemRectToRowRect(nameItemRect); - double screenPixelRatio = q_ptr->getScreenPixelRatio(); - glLineWidth(appPTR->getCurrentSettings()->getDopeSheetEditorNodeSeparationWith() * screenPixelRatio); + glLineWidth(appPTR->getCurrentSettings()->getDopeSheetEditorNodeSeparationWith() * _screenPixelRatio); glColor4f(0.f, 0.f, 0.f, 1.f); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); glVertex2f( rowRect.left(), rowRect.top() ); glVertex2f( rowRect.right(), rowRect.top() ); @@ -1126,7 +1125,6 @@ DopeSheetViewPrivate::drawNodeRowSeparation(const DSNodePtr dsNode) const void DopeSheetViewPrivate::drawRange(const DSNodePtr &dsNode) const { - double screenPixelRatio = q_ptr->getScreenPixelRatio(); // Draw the clip { std::map::const_iterator foundRange = nodeRanges.find( dsNode.get() ); @@ -1177,10 +1175,10 @@ DopeSheetViewPrivate::drawRange(const DSNodePtr &dsNode) const clipRectCenterY = (clipRectZoomCoords.y1 + clipRectZoomCoords.y2) / 2.; GLProtectAttrib aa(GL_CURRENT_BIT | GL_LINE_BIT); - glLineWidth(2 * screenPixelRatio); + glLineWidth(2 * _screenPixelRatio); glColor4f(fillColor.redF(), fillColor.greenF(), fillColor.blueF(), 1.f); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); //horizontal line @@ -1215,7 +1213,7 @@ DopeSheetViewPrivate::drawRange(const DSNodePtr &dsNode) const if (isSelected) { glColor4f(fillColor.redF(), fillColor.greenF(), fillColor.blueF(), 1.f); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINE_LOOP); glVertex2f( clipRectZoomCoords.left(), clipRectZoomCoords.top() ); glVertex2f( clipRectZoomCoords.left(), clipRectZoomCoords.bottom() ); @@ -1231,20 +1229,20 @@ DopeSheetViewPrivate::drawRange(const DSNodePtr &dsNode) const QColor selectionColor; selectionColor.setRgbF(selectionColorRGB[0], selectionColorRGB[1], selectionColorRGB[2]); - QFontMetrics fm(*font); - int fontHeigt = fm.height(); + QFontMetrics fm(*_textFont); + double fontHeight = fm.height() / _screenPixelRatio; QString leftText = QString::number(range.first); QString rightText = QString::number(range.second - 1); - int rightTextW = fm.width(rightText); + double rightTextW = fm.width(rightText) / _screenPixelRatio; QPointF textLeftPos( zoomContext.toZoomCoordinates(zoomContext.toWidgetCoordinates(range.first, 0).x() + 3, 0).x(), - zoomContext.toZoomCoordinates(0, zoomContext.toWidgetCoordinates(0, clipRectCenterY).y() + fontHeigt / 2.).y() ); + zoomContext.toZoomCoordinates(0, zoomContext.toWidgetCoordinates(0, clipRectCenterY).y() + fontHeight / 2.).y() ); - renderText(textLeftPos.x(), textLeftPos.y(), leftText, selectionColor, *font); + renderText(textLeftPos.x(), textLeftPos.y(), leftText, selectionColor, *_textFont); QPointF textRightPos( zoomContext.toZoomCoordinates(zoomContext.toWidgetCoordinates(range.second, 0).x() - rightTextW - 3, 0).x(), - zoomContext.toZoomCoordinates(0, zoomContext.toWidgetCoordinates(0, clipRectCenterY).y() + fontHeigt / 2.).y() ); + zoomContext.toZoomCoordinates(0, zoomContext.toWidgetCoordinates(0, clipRectCenterY).y() + fontHeight / 2.).y() ); - renderText(textRightPos.x(), textRightPos.y(), rightText, selectionColor, *font); + renderText(textRightPos.x(), textRightPos.y(), rightText, selectionColor, *_textFont); } } } // DopeSheetViewPrivate::drawRange @@ -1444,7 +1442,7 @@ DopeSheetViewPrivate::drawTexturedKeyframe(DopeSheetViewPrivate::KeyframeTexture QPointF p = zoomContext.toWidgetCoordinates( rect.right(), rect.bottom() ); p.rx() += 3; p = zoomContext.toZoomCoordinates( p.x(), p.y() ); - renderText(p.x(), p.y(), text, textColor, *font); + renderText(p.x(), p.y(), text, textColor, *_textFont); } } @@ -1506,8 +1504,6 @@ DopeSheetViewPrivate::drawProjectBounds() const double colorR, colorG, colorB; settings->getTimelineBoundsColor(&colorR, &colorG, &colorB); - double screenPixelRatio = q_ptr->getScreenPixelRatio(); - // Perform drawing { GLProtectAttrib a(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); @@ -1515,14 +1511,14 @@ DopeSheetViewPrivate::drawProjectBounds() const glColor4f(colorR, colorG, colorB, 1.f); // Draw start bound - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); glVertex2f(projectStart, top); glVertex2f(projectStart, bottom); glEnd(); // Draw end bound - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); glVertex2f(projectEnd, top); glVertex2f(projectEnd, bottom); @@ -1552,8 +1548,6 @@ DopeSheetViewPrivate::drawCurrentFrameIndicator() double colorR, colorG, colorB; settings->getTimelinePlayheadColor(&colorR, &colorG, &colorB); - double screenPixelRatio = q_ptr->getScreenPixelRatio(); - // Perform drawing { GLProtectAttrib a(GL_CURRENT_BIT | GL_HINT_BIT | GL_ENABLE_BIT | @@ -1566,7 +1560,7 @@ DopeSheetViewPrivate::drawCurrentFrameIndicator() glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glColor4f(colorR, colorG, colorB, 1.f); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); glVertex2f(currentFrame, top); glVertex2f(currentFrame, bottom); @@ -1600,7 +1594,6 @@ void DopeSheetViewPrivate::drawSelectionRect() const { running_in_main_thread_and_context(q_ptr); - double screenPixelRatio = q_ptr->getScreenPixelRatio(); // Perform drawing { @@ -1621,11 +1614,11 @@ DopeSheetViewPrivate::drawSelectionRect() const glVertex2f(selectionRect.x2, selectionRect.y1); glEnd(); - glLineWidth(1.5 * screenPixelRatio); + glLineWidth(1.5 * _screenPixelRatio); // Draw outline glColor4f(0.5, 0.5, 0.5, 1.); - glLineWidth(1.5 * screenPixelRatio); + glLineWidth(1.5 * _screenPixelRatio); glBegin(GL_LINE_LOOP); glVertex2f(selectionRect.x1, selectionRect.y1); glVertex2f(selectionRect.x1, selectionRect.y2); @@ -1646,7 +1639,6 @@ void DopeSheetViewPrivate::drawSelectedKeysBRect() const { running_in_main_thread_and_context(q_ptr); - double screenPixelRatio = q_ptr->getScreenPixelRatio(); // Perform drawing { @@ -1659,7 +1651,7 @@ DopeSheetViewPrivate::drawSelectedKeysBRect() const // Draw outline glColor4f(0.5, 0.5, 0.5, 1.); - glLineWidth(1.5 * screenPixelRatio); + glLineWidth(1.5 * _screenPixelRatio); glBegin(GL_LINE_LOOP); glVertex2f( selectedKeysBRect.left(), selectedKeysBRect.bottom() ); glVertex2f( selectedKeysBRect.left(), selectedKeysBRect.top() ); @@ -1676,7 +1668,7 @@ DopeSheetViewPrivate::drawSelectedKeysBRect() const QLineF verticalLine( zoomContext.toZoomCoordinates(bRectCenterWidgetCoords.x(), bRectCenterWidgetCoords.y() - CROSS_LINE_OFFSET), zoomContext.toZoomCoordinates(bRectCenterWidgetCoords.x(), bRectCenterWidgetCoords.y() + CROSS_LINE_OFFSET) ); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); glVertex2f( horizontalLine.p1().x(), horizontalLine.p1().y() ); glVertex2f( horizontalLine.p2().x(), horizontalLine.p2().y() ); @@ -1714,8 +1706,8 @@ DopeSheetViewPrivate::renderText(double x, return; } - double scalex = (right - left) / w; - double scaley = (top - bottom) / h; + double scalex = (right - left) / (w * _screenPixelRatio); + double scaley = (top - bottom) / (h * _screenPixelRatio); textRenderer.renderText(x, y, scalex, scaley, text, color, font, flags); @@ -3247,6 +3239,15 @@ DopeSheetView::paintGL() return; } + { + double screenPixelRatio = getScreenPixelRatio(); + if (screenPixelRatio != _imp->_screenPixelRatio) { + _imp->_screenPixelRatio = screenPixelRatio; + _imp->_textFont.reset(new QFont(appFont, appFontSize * screenPixelRatio)); + } + } + assert(_imp->_textFont); + double zoomLeft, zoomRight, zoomBottom, zoomTop; zoomLeft = _imp->zoomContext.left(); zoomRight = _imp->zoomContext.right(); diff --git a/Gui/Histogram.cpp b/Gui/Histogram.cpp index c378b9bb3e..6c59330d25 100644 --- a/Gui/Histogram.cpp +++ b/Gui/Histogram.cpp @@ -106,7 +106,8 @@ struct HistogramPrivate , hasBeenModifiedSinceResize(false) , _baseAxisColor(118, 215, 90, 255) , _scaleColor(67, 123, 52, 255) - , _font(appFont, appFontSize) + , _screenPixelRatio(0.) + , _textFont() , textRenderer() , drawCoordinates(false) , xCoordinateStr() @@ -192,7 +193,8 @@ struct HistogramPrivate bool hasBeenModifiedSinceResize; //< true if the user panned or zoomed since the last resize QColor _baseAxisColor; QColor _scaleColor; - QFont _font; + double _screenPixelRatio; + boost::scoped_ptr _textFont; TextRenderer textRenderer; bool drawCoordinates; QString xCoordinateStr; @@ -1151,6 +1153,15 @@ Histogram::paintGL() return; } + { + double screenPixelRatio = getScreenPixelRatio(); + if (screenPixelRatio != _imp->_screenPixelRatio) { + _imp->_screenPixelRatio = screenPixelRatio; + _imp->_textFont.reset(new QFont(appFont, appFontSize * screenPixelRatio)); + } + } + assert(_imp->_textFont); + assert(_imp->zoomCtx.factor() > 0.); double zoomLeft = _imp->zoomCtx.left(); @@ -1570,10 +1581,9 @@ HistogramPrivate::drawScale() return; } - QFontMetrics fontM(_font); + QFontMetrics fm(*_textFont); const double smallestTickSizePixel = 5.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 1000.; // tick size (in pixels) for alpha = 1. - double screenPixelRatio = widget->getScreenPixelRatio(); { @@ -1598,7 +1608,7 @@ HistogramPrivate::drawScale() ticks_fill(half_tick, ticks_max, m1, m2, &ticks); const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; - const double minTickSizeTextPixel = (axis == 0) ? fontM.width( QLatin1String("00") ) : fontM.height(); // AXIS-SPECIFIC + const double minTickSizeTextPixel = ( (axis == 0) ? fm.width( QLatin1String("00") ) : fm.height() ) / _screenPixelRatio; // AXIS-SPECIFIC const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; for (int i = m1; i <= m2; ++i) { double value = i * smallTickSize + offset; @@ -1607,7 +1617,7 @@ HistogramPrivate::drawScale() glColor4f(_baseAxisColor.redF(), _baseAxisColor.greenF(), _baseAxisColor.blueF(), alpha); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); if (axis == 0) { glVertex2f( value, btmLeft.y() ); // AXIS-SPECIFIC @@ -1622,23 +1632,23 @@ HistogramPrivate::drawScale() if (tickSize > minTickSizeText) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = QString::number(value); - const int sSizePixel = (axis == 0) ? fontM.width(s) : fontM.height(); // AXIS-SPECIFIC + const double sSizePixel = ( (axis == 0) ? fm.width(s) : fm.height() ) / _screenPixelRatio; // AXIS-SPECIFIC if (tickSizePixel > sSizePixel) { - const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; + const double sSizeFullPixel = sSizePixel + minTickSizeTextPixel; double alphaText = 1.0; //alpha; if (tickSizePixel < sSizeFullPixel) { // when the text size is between sSizePixel and sSizeFullPixel, // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } - alphaText = std::min(alphaText, alpha); // don't draw more opaque than tcks + //alphaText = std::min(alphaText, alpha); // don't draw more opaque than ticks QColor c = _scaleColor; c.setAlpha(255 * alphaText); glCheckError(); if (axis == 0) { - widget->renderText(value, btmLeft.y(), s, c, _font, Qt::AlignHCenter); // AXIS-SPECIFIC + widget->renderText(value, btmLeft.y(), s, c, *_textFont, Qt::AlignHCenter); // AXIS-SPECIFIC } else { - widget->renderText(btmLeft.x(), value, s, c, _font, Qt::AlignVCenter); // AXIS-SPECIFIC + widget->renderText(btmLeft.x(), value, s, c, *_textFont, Qt::AlignVCenter); // AXIS-SPECIFIC } } } @@ -1655,12 +1665,13 @@ HistogramPrivate::drawWarnings() assert( qApp && qApp->thread() == QThread::currentThread() ); assert( QGLContext::currentContext() == widget->context() ); if (mipMapLevel > 0) { - QFontMetrics m(_font); + QFontMetrics fm(*_textFont); QString str( tr("Image downscaled") ); - int strWidth = m.width(str); - QPointF pos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 5 * m.height() + 30); + double strWidth = fm.width(str) / _screenPixelRatio; + double strHeight = fm.height() / _screenPixelRatio; + QPointF pos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 5 * strHeight + 30); glCheckError(); - widget->renderText(pos.x(), pos.y(), str, QColor(220, 220, 0), _font); + widget->renderText(pos.x(), pos.y(), str, QColor(220, 220, 0), *_textFont); glCheckError(); } } @@ -1669,7 +1680,6 @@ HistogramPrivate::drawWarnings() void HistogramPrivate::drawMissingImage() { - double screenPixelRatio = widget->getScreenPixelRatio(); QPointF topLeft = zoomCtx.toZoomCoordinates(0, 0); QPointF btmRight = zoomCtx.toZoomCoordinates( widget->width(), widget->height() ); QPointF topRight( btmRight.x(), topLeft.y() ); @@ -1678,22 +1688,22 @@ HistogramPrivate::drawMissingImage() GLProtectAttrib a(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT); glColor4f(0.9, 0.9, 0, 1); - glLineWidth(1.5 * screenPixelRatio); + glLineWidth(1.5 * _screenPixelRatio); glBegin(GL_LINES); glVertex2f( topLeft.x(), topLeft.y() ); glVertex2f( btmRight.x(), btmRight.y() ); glVertex2f( btmLeft.x(), btmLeft.y() ); glVertex2f( topRight.x(), topRight.y() ); glEnd(); - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); } QString txt( tr("Missing image") ); - QFontMetrics m(_font); - int strWidth = m.width(txt); - QPointF pos = zoomCtx.toZoomCoordinates(widget->width() / 2. - strWidth / 2., m.height() + 10); + QFontMetrics fm(*_textFont); + int strWidth = fm.width(txt) / _screenPixelRatio; + QPointF pos = zoomCtx.toZoomCoordinates(widget->width() / 2. - strWidth / 2., fm.height() / _screenPixelRatio + 10); glCheckError(); - widget->renderText(pos.x(), pos.y(), txt, QColor(220, 0, 0), _font); + widget->renderText(pos.x(), pos.y(), txt, QColor(220, 0, 0), *_textFont); glCheckError(); } @@ -1701,7 +1711,6 @@ void HistogramPrivate::drawViewerPicker() { // always running in the main thread - double screenPixelRatio = widget->getScreenPixelRatio(); assert( qApp && qApp->thread() == QThread::currentThread() ); assert( QGLContext::currentContext() == widget->context() ); @@ -1710,8 +1719,8 @@ HistogramPrivate::drawViewerPicker() QPointF topLeft = zoomCtx.toZoomCoordinates(0, 0); QPointF btmRight = zoomCtx.toZoomCoordinates(widget->width(), wHeight); - //QFontMetrics m(_font, 0); - //double yPos = zoomCtx.toZoomCoordinates(0,wHeight - m.height() * 2.).y(); + //QFontMetrics fm(_textFont, 0); + //double yPos = zoomCtx.toZoomCoordinates(0,wHeight - fm.height() * 2. / _screenPixelRatio).y(); QColor color; double imgColor[4] = {0., 0., 0., 0.}; for (std::size_t i = 0; i < (std::size_t)std::min( (int)viewerPickerColor.size(), 3 ); ++i) { @@ -1721,42 +1730,42 @@ HistogramPrivate::drawViewerPicker() if (mode == Histogram::eDisplayModeY) { glColor3f(0.398979, 0.398979, 0.398979); double luminance = 0.299 * imgColor[0] + 0.587 * imgColor[1] + 0.114 * imgColor[2]; - glLineWidth(2. * screenPixelRatio); + glLineWidth(2. * _screenPixelRatio); glBegin(GL_LINES); glVertex2d( luminance, topLeft.y() ); glVertex2d( luminance, btmRight.y() ); glEnd(); } else if (mode == Histogram::eDisplayModeR) { glColor3f(0.398979, 0.398979, 0.398979); - glLineWidth(2. * screenPixelRatio); + glLineWidth(2. * _screenPixelRatio); glBegin(GL_LINES); glVertex2d( imgColor[0], topLeft.y() ); glVertex2d( imgColor[0], btmRight.y() ); glEnd(); } else if (mode == Histogram::eDisplayModeG) { glColor3f(0.398979, 0.398979, 0.398979); - glLineWidth(2. * screenPixelRatio); + glLineWidth(2. * _screenPixelRatio); glBegin(GL_LINES); glVertex2d( imgColor[1], topLeft.y() ); glVertex2d( imgColor[1], btmRight.y() ); glEnd(); } else if (mode == Histogram::eDisplayModeB) { glColor3f(0.398979, 0.398979, 0.398979); - glLineWidth(2. * screenPixelRatio); + glLineWidth(2. * _screenPixelRatio); glBegin(GL_LINES); glVertex2d( imgColor[2], topLeft.y() ); glVertex2d( imgColor[2], btmRight.y() ); glEnd(); } else if (mode == Histogram::eDisplayModeA) { glColor3f(0.398979, 0.398979, 0.398979); - glLineWidth(2. * screenPixelRatio); + glLineWidth(2. * _screenPixelRatio); glBegin(GL_LINES); glVertex2d( imgColor[3], topLeft.y() ); glVertex2d( imgColor[3], btmRight.y() ); glEnd(); } else if (mode == Histogram::eDisplayModeRGB) { glColor3f(0.851643, 0.196936, 0.196936); - glLineWidth(2. * screenPixelRatio); + glLineWidth(2. * _screenPixelRatio); glBegin(GL_LINES); glVertex2d( imgColor[0], topLeft.y() ); glVertex2d( imgColor[0], btmRight.y() ); @@ -1776,7 +1785,7 @@ HistogramPrivate::drawViewerPicker() glEnd(); } - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); } // HistogramPrivate::drawViewerPicker void @@ -1787,12 +1796,13 @@ HistogramPrivate::drawPicker() assert( QGLContext::currentContext() == widget->context() ); glCheckError(); - QFontMetrics m(_font, 0); - int strWidth = std::max( std::max( std::max( m.width(rValueStr), m.width(gValueStr) ), m.width(bValueStr) ), m.width(xCoordinateStr) ); - QPointF xPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, m.height() + 10); - QPointF rPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 2 * m.height() + 15); - QPointF gPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 3 * m.height() + 20); - QPointF bPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 4 * m.height() + 25); + QFontMetrics fm(*_textFont, 0); + double strWidth = std::max( std::max( std::max( fm.width(rValueStr), fm.width(gValueStr) ), fm.width(bValueStr) ), fm.width(xCoordinateStr) ) / _screenPixelRatio; + double strHeight = fm.height() / _screenPixelRatio; + QPointF xPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, strHeight + 10); + QPointF rPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 2 * strHeight + 15); + QPointF gPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 3 * strHeight + 20); + QPointF bPos = zoomCtx.toZoomCoordinates(widget->width() - strWidth - 10, 4 * strHeight + 25); QColor xColor, rColor, gColor, bColor; // Text-aware Magic colors (see recipe below): @@ -1818,10 +1828,10 @@ HistogramPrivate::drawPicker() bColor.setRgbF(0.345293, 0.345293, 1); glCheckError(); - widget->renderText(xPos.x(), xPos.y(), xCoordinateStr, xColor, _font); - widget->renderText(rPos.x(), rPos.y(), rValueStr, rColor, _font); - widget->renderText(gPos.x(), gPos.y(), gValueStr, gColor, _font); - widget->renderText(bPos.x(), bPos.y(), bValueStr, bColor, _font); + widget->renderText(xPos.x(), xPos.y(), xCoordinateStr, xColor, *_textFont); + widget->renderText(rPos.x(), rPos.y(), rValueStr, rColor, *_textFont); + widget->renderText(gPos.x(), gPos.y(), gValueStr, gColor, *_textFont); + widget->renderText(bPos.x(), bPos.y(), bValueStr, bColor, *_textFont); glCheckError(); } @@ -1923,7 +1933,6 @@ HistogramPrivate::drawHistogramCPU() // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); assert( QGLContext::currentContext() == widget->context() ); - double screenPixelRatio = widget->getScreenPixelRatio(); glCheckError(); { @@ -1937,7 +1946,7 @@ HistogramPrivate::drawHistogramCPU() double binSize = (vmax - vmin) / binsCount; - glLineWidth(1. * screenPixelRatio); + glLineWidth(1. * _screenPixelRatio); glBegin(GL_LINES); for (unsigned int i = 0; i < binsCount; ++i) { double binMinX = vmin + i * binSize; @@ -2034,8 +2043,8 @@ Histogram::renderText(double x, if ( (w <= 0) || (h <= 0) || (right <= left) || (top <= bottom) ) { return; } - double scalex = (right - left) / w; - double scaley = (top - bottom) / h; + double scalex = (right - left) / (w * _imp->_screenPixelRatio); + double scaley = (top - bottom) / (h * _imp->_screenPixelRatio); _imp->textRenderer.renderText(x, y, scalex, scaley, text, color, font, flags); glCheckError(); } diff --git a/Gui/ScaleSliderQWidget.cpp b/Gui/ScaleSliderQWidget.cpp index 470d7dfcbd..355ebf52f4 100644 --- a/Gui/ScaleSliderQWidget.cpp +++ b/Gui/ScaleSliderQWidget.cpp @@ -552,7 +552,7 @@ ScaleSliderQWidget::paintEvent(QPaintEvent* /*e*/) // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } - alphaText = std::min(alphaText, alpha); // don't draw more opaque than tcks + //alphaText = std::min(alphaText, alpha); // don't draw more opaque than ticks QColor c = _imp->readOnly || !isEnabled() ? Qt::black : textColor; c.setAlphaF(alphaText); p.setFont(_imp->font); diff --git a/Gui/TimeLineGui.cpp b/Gui/TimeLineGui.cpp index bf3e8b218a..62a8bf1b12 100644 --- a/Gui/TimeLineGui.cpp +++ b/Gui/TimeLineGui.cpp @@ -157,7 +157,8 @@ struct TimelineGuiPrivate int mouseMoveX; ///< widget X coordinate of last mousemove position TimeLineZoomContext tlZoomCtx; TextRenderer textRenderer; - QFont font; + double _screenPixelRatio; + boost::scoped_ptr _textFont; bool firstPaint; CachedFrames cachedFrames; mutable QMutex boundariesMutex; @@ -187,7 +188,8 @@ struct TimelineGuiPrivate , mouseMoveX(0) , tlZoomCtx() , textRenderer() - , font(appFont, appFontSize) + , _screenPixelRatio(0.) + , _textFont() , firstPaint(true) , cachedFrames() , boundariesMutex() @@ -353,6 +355,15 @@ TimeLineGui::paintGL() glCheckError(); + { + double screenPixelRatio = _imp->viewerTab->getViewer()->getScreenPixelRatio(); + if (screenPixelRatio != _imp->_screenPixelRatio) { + _imp->_screenPixelRatio = screenPixelRatio; + _imp->_textFont.reset(new QFont(appFont, appFontSize * screenPixelRatio)); + } + } + assert(_imp->_textFont); + SequenceTime leftBound, rightBound; { QMutexLocker k(&_imp->boundariesMutex); @@ -387,7 +398,6 @@ TimeLineGui::paintGL() double clearR, clearG, clearB; SettingsPtr settings = appPTR->getCurrentSettings(); settings->getTimelineBGColor(&clearR, &clearG, &clearB); - double screenPixelRatio = _imp->viewerTab->getViewer()->getScreenPixelRatio(); if ( (left == right) || (top == bottom) ) { glClearColor(clearR, clearG, clearB, 1.); @@ -425,20 +435,31 @@ TimeLineGui::paintGL() firstFrame = (double)f; lastFrame = (double)l; } - QPointF firstFrameWidgetPos = toWidgetCoordinates(firstFrame, 0); - QPointF lastFrameWidgetPos = toWidgetCoordinates(lastFrame, 0); - - glScissor( firstFrameWidgetPos.x(), 0, - lastFrameWidgetPos.x() - firstFrameWidgetPos.x(), height() ); double bgR, bgG, bgB; settings->getBaseColor(&bgR, &bgG, &bgB); +#if 0 + // solution using glScissor + QPointF firstFrameWidgetPos = toWidgetCoordinates(firstFrame, 0); + QPointF lastFrameWidgetPos = toWidgetCoordinates(lastFrame, 0); + + glScissor( firstFrameWidgetPos.x() * _imp->_screenPixelRatio, 0, + (lastFrameWidgetPos.x() - firstFrameWidgetPos.x()) * _imp->_screenPixelRatio, height() * _imp->_screenPixelRatio); glEnable(GL_SCISSOR_TEST); glClearColor(bgR, bgG, bgB, 1.); glClear(GL_COLOR_BUFFER_BIT); glCheckErrorIgnoreOSXBug(); glDisable(GL_SCISSOR_TEST); +#else + glColor4f(bgR, bgG, bgB, 1.); + glBegin(GL_POLYGON); + glVertex2f( firstFrame, btmLeft.y() ); + glVertex2f( firstFrame, topRight.y() ); + glVertex2f( lastFrame, topRight.y() ); + glVertex2f( lastFrame, btmLeft.y() ); + glEnd(); +#endif glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -457,8 +478,9 @@ TimeLineGui::paintGL() } - QFontMetrics fontM(_imp->font, 0); - double lineYPosWidget = height() - 1 - fontM.height() - TO_DPIY(TICK_HEIGHT) / 2.; + QFontMetrics fm(*_imp->_textFont, 0); + double fmHeight = fm.height() / _imp->_screenPixelRatio; + double lineYPosWidget = height() - 1 - fmHeight - TO_DPIY(TICK_HEIGHT) / 2.; double lineYpos = toTimeLineCoordinates(0, lineYPosWidget).y(); double cachedLineYPos = toTimeLineCoordinates(0, lineYPosWidget + 1).y(); @@ -486,7 +508,7 @@ TimeLineGui::paintGL() glColor4f(txtR / 2., txtG / 2., txtB / 2., 1.); - glLineWidth(1.5 * screenPixelRatio); + glLineWidth(1.5 * _imp->_screenPixelRatio); glBegin(GL_LINES); glVertex2f(btmLeft.x(), lineYpos); glVertex2f(topRight.x(), lineYpos); @@ -496,8 +518,8 @@ TimeLineGui::paintGL() #if (__GNUC__ == 8 && __GNUC_MINOR__ >= 1 && __GNUC_MINOR__ < 3) && !defined(ENFORCE_GCC8) #error "Timeline GUI is wrong with GCC 8.1 (and maybe GCC 8.2), see https://github.com/NatronGitHub/Natron/issues/279" #endif - double tickBottom = toTimeLineCoordinates( 0, height() - 1 - fontM.height() ).y(); - double tickTop = toTimeLineCoordinates( 0, height() - 1 - fontM.height() - TO_DPIY(TICK_HEIGHT) ).y(); + double tickBottom = toTimeLineCoordinates( 0, height() - 1 - fmHeight ).y(); + double tickTop = toTimeLineCoordinates( 0, height() - 1 - fmHeight - TO_DPIY(TICK_HEIGHT) ).y(); const double smallestTickSizePixel = 30.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 200.; // tick size (in pixels) for alpha = 1. const double rangePixel = width(); @@ -520,7 +542,7 @@ TimeLineGui::paintGL() ticks_fill(half_tick, ticks_max, m1, m2, &ticks); const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; - const double minTickSizeTextPixel = _imp->isTimeFormatFrames ? fontM.width( QLatin1String("00000") ) : fontM.width( QLatin1String("00:00:00:00") ); // AXIS-SPECIFIC + const double minTickSizeTextPixel = ( _imp->isTimeFormatFrames ? fm.width( QLatin1String("00000") ) : fm.width( QLatin1String("00:00:00:00") ) ) / _imp->_screenPixelRatio; // AXIS-SPECIFIC const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; for (int i = m1; i <= m2; ++i) { double value = i * smallTickSize + offset; @@ -534,7 +556,7 @@ TimeLineGui::paintGL() continue; } glColor4f(txtR, txtG, txtB, alpha); - glLineWidth(1.5 * screenPixelRatio); + glLineWidth(1.5 * _imp->_screenPixelRatio); glBegin(GL_LINES); glVertex2f(value, tickBottom); glVertex2f(value, tickTop); @@ -544,7 +566,7 @@ TimeLineGui::paintGL() if (tickSize > minTickSizeText) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = _imp->isTimeFormatFrames ? QString::number(value) : timecodeString(value, fps); - const int sSizePixel = fontM.width(s); + const int sSizePixel = fm.width(s) / _imp->_screenPixelRatio; if (tickSizePixel > sSizePixel) { const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; double alphaText = 1.0; //alpha; @@ -553,14 +575,14 @@ TimeLineGui::paintGL() // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } - alphaText = std::min(alphaText, alpha); // don't draw more opaque than tcks + //alphaText = std::min(alphaText, alpha); // don't draw more opaque than ticks QColor c; c.setRgbF( Image::clamp(txtR, 0., 1.), Image::clamp(txtG, 0., 1.), Image::clamp(txtB, 0., 1.) ); c.setAlpha(255 * alphaText); glCheckError(); - renderText(value, btmLeft.y(), s, c, _imp->font, Qt::AlignHCenter); + renderText(value, btmLeft.y(), s, c, *_imp->_textFont, Qt::AlignHCenter); } } } @@ -655,7 +677,7 @@ TimeLineGui::paintGL() glEnd(); glCheckErrorIgnoreOSXBug(); - renderText(currentBtm.x(), currentTopRight.y(), currentNumber, currentColor, _imp->font, Qt::AlignHCenter); + renderText(currentBtm.x(), currentTopRight.y(), currentNumber, currentColor, *_imp->_textFont, Qt::AlignHCenter); } //draw the bounds and the current time cursor @@ -683,7 +705,7 @@ TimeLineGui::paintGL() QString currentFrameStr = _imp->isTimeFormatFrames ? QString::number(currentTime) : timecodeString(currentTime, fps); double cursorTextXposWidget = cursorBtmWidgetCoord.x(); double cursorTextPos = toTimeLine(cursorTextXposWidget); - renderText(cursorTextPos, cursorTopLeft.y(), currentFrameStr, actualCursorColor, _imp->font, Qt::AlignHCenter); + renderText(cursorTextPos, cursorTopLeft.y(), currentFrameStr, actualCursorColor, *_imp->_textFont, Qt::AlignHCenter); glBegin(GL_POLYGON); glVertex2f( cursorBtm.x(), cursorBtm.y() ); glVertex2f( cursorTopLeft.x(), cursorTopLeft.y() ); @@ -704,7 +726,7 @@ TimeLineGui::paintGL() double leftBoundTextXposWidget = toWidgetCoordinates( ( leftBoundBtm.x() + leftBoundBtmRight.x() ) / 2., 0 ).x(); double leftBoundTextPos = toTimeLine(leftBoundTextXposWidget); renderText(leftBoundTextPos, leftBoundTop.y(), - leftBoundStr, boundsColor, _imp->font, Qt::AlignHCenter); + leftBoundStr, boundsColor, *_imp->_textFont, Qt::AlignHCenter); } glColor4f(boundsR, boundsG, boundsB, 1.); glBegin(GL_POLYGON); @@ -721,7 +743,7 @@ TimeLineGui::paintGL() double rightBoundTextXposWidget = toWidgetCoordinates( ( rightBoundBtm.x() + rightBoundBtmLeft.x() ) / 2., 0 ).x(); double rightBoundTextPos = toTimeLine(rightBoundTextXposWidget); renderText(rightBoundTextPos, rightBoundTop.y(), - rightBoundStr, boundsColor, _imp->font, Qt::AlignHCenter); + rightBoundStr, boundsColor, *_imp->_textFont, Qt::AlignHCenter); } glColor4f(boundsR, boundsG, boundsB, 1.); glCheckError(); @@ -739,7 +761,7 @@ TimeLineGui::paintGL() glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glCheckError(); - glLineWidth(2 * screenPixelRatio); + glLineWidth(2 * _imp->_screenPixelRatio); glBegin(GL_LINES); for (CachedFrames::const_iterator i = _imp->cachedFrames.begin(); i != _imp->cachedFrames.end(); ++i) { if ( ( i->time >= btmLeft.x() ) && ( i->time <= topRight.x() ) ) { @@ -755,7 +777,7 @@ TimeLineGui::paintGL() glEnd(); ///now draw keyframes - glLineWidth(2 * screenPixelRatio); + glLineWidth(2 * _imp->_screenPixelRatio); glBegin(GL_LINES); glColor4f(kfR, kfG, kfB, 1.); std::list remainingUserKeys; @@ -807,9 +829,9 @@ TimeLineGui::paintGL() glEnd(); /*QString kfStr = QString::number(*it); - double kfXposWidget = kfBtmWidgetCoord.x() - fontM.width(kfStr) / 2.; + double kfXposWidget = kfBtmWidgetCoord.x() - fontM.width(kfStr) / (2. * _imp->_screenPixelRatio); double kfTextPos = toTimeLine(kfXposWidget); - renderText(kfTextPos,kfTopLeft.y(), kfStr, userKeyColor, _imp->font, Qt::AlignHCenter);*/ + renderText(kfTextPos,kfTopLeft.y(), kfStr, userKeyColor, *_imp->_textFont, Qt::AlignHCenter);*/ } glCheckErrorIgnoreOSXBug(); glDisable(GL_POLYGON_SMOOTH); @@ -842,8 +864,8 @@ TimeLineGui::renderText(double x, if ( (w <= 0) || (h <= 0) || (right <= left) || (top <= bottom) ) { return; } - double scalex = (right - left) / w; - double scaley = (top - bottom) / h; + double scalex = (right - left) / (w * _imp->_screenPixelRatio); + double scaley = (top - bottom) / (h * _imp->_screenPixelRatio); _imp->textRenderer.renderText(x, y, scalex, scaley, text, color, font, flags); glCheckError(); } diff --git a/Gui/ViewerGL.cpp b/Gui/ViewerGL.cpp index 545ac0af81..47bb2784d9 100644 --- a/Gui/ViewerGL.cpp +++ b/Gui/ViewerGL.cpp @@ -150,15 +150,7 @@ ViewerGL::textFont() const // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); - return _imp->textFont; -} - -void -ViewerGL::setTextFont(const QFont & f) -{ - // always running in the main thread - assert( qApp && qApp->thread() == QThread::currentThread() ); - _imp->textFont = f; + return *_imp->_textFont; } /** @@ -265,6 +257,16 @@ ViewerGL::paintGL() } glCheckError(); + + { + double screenPixelRatio = getScreenPixelRatio(); + if (screenPixelRatio != _imp->_screenPixelRatio) { + _imp->_screenPixelRatio = screenPixelRatio; + _imp->_textFont.reset(new QFont(appFont, appFontSize * screenPixelRatio)); + } + } + assert(_imp->_textFont); + double zoomLeft, zoomRight, zoomBottom, zoomTop; { QMutexLocker l(&_imp->zoomCtxMutex); @@ -598,7 +600,8 @@ ViewerGL::drawOverlay(unsigned int mipMapLevel) // Draw format { - renderText(canonicalFormat.right(), canonicalFormat.bottom(), _imp->currentViewerInfo_resolutionOverlay[i], _imp->textRenderingColor, _imp->textFont); + assert(_imp->_textFont); + renderText(canonicalFormat.right(), canonicalFormat.bottom(), _imp->currentViewerInfo_resolutionOverlay[i], _imp->textRenderingColor, *_imp->_textFont); QPoint topRight( canonicalFormat.right(), canonicalFormat.top() ); @@ -636,10 +639,11 @@ ViewerGL::drawOverlay(unsigned int mipMapLevel) if (dataW != canonicalFormat) { + assert(_imp->_textFont); renderText(dataW.right(), dataW.top(), - _imp->currentViewerInfo_topRightBBOXoverlay[i], _imp->rodOverlayColor, _imp->textFont); + _imp->currentViewerInfo_topRightBBOXoverlay[i], _imp->rodOverlayColor, *_imp->_textFont); renderText(dataW.left(), dataW.bottom(), - _imp->currentViewerInfo_btmLeftBBOXoverlay[i], _imp->rodOverlayColor, _imp->textFont); + _imp->currentViewerInfo_btmLeftBBOXoverlay[i], _imp->rodOverlayColor, *_imp->_textFont); glCheckError(); QPointF topRight2( dataW.right(), dataW.top() ); @@ -1157,20 +1161,21 @@ ViewerGL::drawPersistentMessage() assert( qApp && qApp->thread() == QThread::currentThread() ); assert( QGLContext::currentContext() == context() ); - QFontMetrics metrics( _imp->textFont ); + assert(_imp->_textFont); int offset = 10; - double metricsHeightZoomCoord; + double fmHeightZoomCoord; QPointF topLeft, bottomRight, offsetZoomCoord; - { + QFontMetrics fm( *_imp->_textFont ); + double fmHeight = fm.height() / _imp->_screenPixelRatio; QMutexLocker l(&_imp->zoomCtxMutex); topLeft = _imp->zoomCtx.toZoomCoordinates(0, 0); - bottomRight = _imp->zoomCtx.toZoomCoordinates( _imp->zoomCtx.screenWidth(), _imp->persistentMessages.size() * (metrics.height() + offset) ); + bottomRight = _imp->zoomCtx.toZoomCoordinates( _imp->zoomCtx.screenWidth(), _imp->persistentMessages.size() * (fmHeight + offset) ); offsetZoomCoord = _imp->zoomCtx.toZoomCoordinates(PERSISTENT_MESSAGE_LEFT_OFFSET_PIXELS, offset); - metricsHeightZoomCoord = topLeft.y() - _imp->zoomCtx.toZoomCoordinates( 0, metrics.height() ).y(); + fmHeightZoomCoord = topLeft.y() - _imp->zoomCtx.toZoomCoordinates( 0, fmHeight ).y(); } offsetZoomCoord.ry() = topLeft.y() - offsetZoomCoord.y(); - QPointF textPos(offsetZoomCoord.x(), topLeft.y() - (offsetZoomCoord.y() / 2.) - metricsHeightZoomCoord); + QPointF textPos(offsetZoomCoord.x(), topLeft.y() - (offsetZoomCoord.y() / 2.) - fmHeightZoomCoord); { GLProtectAttrib a(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); @@ -1191,8 +1196,9 @@ ViewerGL::drawPersistentMessage() for (int j = 0; j < _imp->persistentMessages.size(); ++j) { - renderText(textPos.x(), textPos.y(), _imp->persistentMessages.at(j), _imp->textRenderingColor, _imp->textFont); - textPos.setY( textPos.y() - ( metricsHeightZoomCoord + offsetZoomCoord.y() ) ); /*metrics.height() * 2 * zoomScreenPixelHeight*/ + assert(_imp->_textFont); + renderText(textPos.x(), textPos.y(), _imp->persistentMessages.at(j), _imp->textRenderingColor, *_imp->_textFont); + textPos.setY( textPos.y() - ( fmHeightZoomCoord + offsetZoomCoord.y() ) ); /*metrics.height() * 2 * zoomScreenPixelHeight*/ } glCheckError(); } // GLProtectAttrib a(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); @@ -3302,8 +3308,8 @@ ViewerGL::renderText(double x, if ( (w <= 0) || (h <= 0) || (right <= left) || (top <= bottom) ) { return; } - double scalex = (right - left) / w; - double scaley = (top - bottom) / h; + double scalex = (right - left) / (w * _imp->_screenPixelRatio); + double scaley = (top - bottom) / (h * _imp->_screenPixelRatio); _imp->textRenderer.renderText(x, y, scalex, scaley, text, color, font, flags); glCheckError(); } @@ -3314,7 +3320,7 @@ ViewerGL::updatePersistentMessageToWidth(int w) // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); - if ( !_imp->viewerTab || !_imp->viewerTab->getGui() ) { + if ( !_imp->viewerTab || !_imp->viewerTab->getGui() || !_imp->_textFont ) { return; } @@ -3357,10 +3363,12 @@ ViewerGL::updatePersistentMessageToWidth(int w) } _imp->persistentMessageType = type; - QFontMetrics fm(_imp->textFont); + assert(_imp->_textFont); + QFontMetrics fm(*_imp->_textFont); for (int i = 0; i < allMessages.size(); ++i) { - QStringList wordWrapped = wordWrap(fm, allMessages[i], w - PERSISTENT_MESSAGE_LEFT_OFFSET_PIXELS); + QStringList wordWrapped = wordWrap( fm, allMessages[i], + _imp->_screenPixelRatio * (w - PERSISTENT_MESSAGE_LEFT_OFFSET_PIXELS) ); for (int j = 0; j < wordWrapped.size(); ++j) { _imp->persistentMessages.push_back(wordWrapped[j]); } diff --git a/Gui/ViewerGL.h b/Gui/ViewerGL.h index 7881ef0217..571c854700 100644 --- a/Gui/ViewerGL.h +++ b/Gui/ViewerGL.h @@ -80,9 +80,6 @@ GCC_DIAG_SUGGEST_OVERRIDE_ON virtual QSize sizeHint() const OVERRIDE FINAL; const QFont & textFont() const; - void setTextFont(const QFont & f); - - /** *@returns Returns true if the viewer is displaying something. **/ diff --git a/Gui/ViewerGLPrivate.cpp b/Gui/ViewerGLPrivate.cpp index e820a67371..b98c8ae00a 100644 --- a/Gui/ViewerGLPrivate.cpp +++ b/Gui/ViewerGLPrivate.cpp @@ -82,7 +82,8 @@ ViewerGL::Implementation::Implementation(ViewerGL* this_, , textRenderingColor(200, 200, 200, 255) , displayWindowOverlayColor(125, 125, 125, 255) , rodOverlayColor(100, 100, 100, 255) - , textFont(appFont, appFontSize) + , _screenPixelRatio(0.) + , _textFont() , overlay(true) , updatingTexture(false) , clearColor(0, 0, 0, 255) diff --git a/Gui/ViewerGLPrivate.h b/Gui/ViewerGLPrivate.h index 438a48cdb4..b0543962c1 100644 --- a/Gui/ViewerGLPrivate.h +++ b/Gui/ViewerGLPrivate.h @@ -172,7 +172,8 @@ struct ViewerGL::Implementation const QColor textRenderingColor; const QColor displayWindowOverlayColor; const QColor rodOverlayColor; - QFont textFont; + double _screenPixelRatio; + boost::scoped_ptr _textFont; bool overlay; /*!< True if the user enabled overlay display*/ bool updatingTexture; QColor clearColor;