# HG changeset patch
# Parent  6b3c78f84d3b30b34db3e464bb8c2db0ee5fceb5

diff -r 6b3c78f84d3b libgui/graphics/GLCanvas.cc
--- a/libgui/graphics/GLCanvas.cc	Mon Jan 15 16:38:16 2018 -0500
+++ b/libgui/graphics/GLCanvas.cc	Thu Jan 18 13:12:26 2018 -0800
@@ -26,10 +26,15 @@
 
 #include "gl-render.h"
 #include "graphics.h"
+#include "display.h"
 
 #include "GLCanvas.h"
 #include "gl-select.h"
 
+#include <QtGlobal>
+#include <QApplication>
+#include <QScreen>
+
 namespace QtHandles
 {
 #if defined (HAVE_QOPENGLWIDGET)
@@ -51,6 +56,12 @@
   {
     setFocusPolicy (Qt::ClickFocus);
     setFocus ();
+
+    #if defined (HAVE_QT5)
+       QScreen *screen = QApplication::screens().at(0);
+       double screen_scale = screen->devicePixelRatio();
+       octave::display_info::set_screen_scale (screen_scale);
+    #endif
   }
 
   GLCanvas::~GLCanvas (void)
diff -r 6b3c78f84d3b libinterp/corefcn/display.h
--- a/libinterp/corefcn/display.h	Mon Jan 15 16:38:16 2018 -0500
+++ b/libinterp/corefcn/display.h	Thu Jan 18 13:12:26 2018 -0800
@@ -39,28 +39,32 @@
 
     display_info (void)
       : m_ht (1), m_wd (1), m_dp (0),
-        m_rx (72), m_ry (72), m_dpy_avail (false), m_err_msg ()
+        m_rx (72), m_ry (72), m_screen_scale (1.0),
+        m_dpy_avail (false), m_err_msg ()
     {
       init ();
     }
 
     explicit display_info (const std::string& dpy_name)
       : m_ht (1), m_wd (1), m_dp (0),
-        m_rx (72), m_ry (72), m_dpy_avail (false), m_err_msg ()
+        m_rx (72), m_ry (72), m_screen_scale (1.0),
+        m_dpy_avail (false), m_err_msg ()
     {
       init (dpy_name);
     }
 
     explicit display_info (bool query)
       : m_ht (1), m_wd (1), m_dp (0),
-        m_rx (72), m_ry (72), m_dpy_avail (false), m_err_msg ()
+        m_rx (72), m_ry (72), m_screen_scale (1.0),
+        m_dpy_avail (false), m_err_msg ()
     {
       init ("", query);
     }
 
     explicit display_info (const std::string& dpy_name, bool query)
       : m_ht (1), m_wd (1), m_dp (0),
-        m_rx (72), m_ry (72), m_dpy_avail (false), m_err_msg ()
+        m_rx (72), m_ry (72), m_screen_scale (1.0),
+        m_dpy_avail (false), m_err_msg ()
     {
       init (dpy_name, query);
     }
@@ -92,6 +96,17 @@
       return instance_ok () ? instance->do_y_dpi () : 0;
     }
 
+    static double screen_scale (void)
+    {
+      return instance_ok () ? instance->do_screen_scale () : 0;
+    }
+
+    static void set_screen_scale (double screen_scale)
+    {
+      if (instance_ok ())
+        instance->do_set_screen_scale (screen_scale);
+    }
+
     static bool display_available (void)
     {
       std::string msg;
@@ -125,6 +140,9 @@
     double m_rx;
     double m_ry;
 
+    // The pixel scale factor for retina devices (used to draw OpenGL properly).
+    double m_screen_scale;
+
     bool m_dpy_avail;
 
     std::string m_err_msg;
@@ -135,6 +153,11 @@
 
     double do_x_dpi (void) const { return m_rx; }
     double do_y_dpi (void) const { return m_ry; }
+    double do_screen_scale (void) const { return m_screen_scale; }
+    void do_set_screen_scale (double screen_scale)
+    {
+      m_screen_scale = screen_scale;
+    }
 
     bool do_display_available (std::string& msg) const
     {
diff -r 6b3c78f84d3b libinterp/corefcn/gl-render.cc
--- a/libinterp/corefcn/gl-render.cc	Mon Jan 15 16:38:16 2018 -0500
+++ b/libinterp/corefcn/gl-render.cc	Thu Jan 18 13:12:26 2018 -0800
@@ -37,6 +37,7 @@
 
 #include "errwarn.h"
 #include "gl-render.h"
+#include "display.h"
 #include "oct-opengl.h"
 #include "text-renderer.h"
 
@@ -1156,7 +1157,13 @@
     glMultMatrixd (x_mat1.data ());
     glMatrixMode (GL_PROJECTION);
     glLoadIdentity ();
-    glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
+    
+    float screen_scale_inverse = 1.0 / display_info::screen_scale ();
+    vw[2] = octave::math::round (screen_scale_inverse *
+				 static_cast<float> (vw[2]));
+    vw[3] = octave::math::round (screen_scale_inverse *
+				 static_cast<float> (vw[3]));
+    glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);    
     glMultMatrixd (x_mat2.data ());
     glMatrixMode (GL_MODELVIEW);
 
@@ -3538,7 +3545,14 @@
     glMatrixMode (GL_PROJECTION);
     glPushMatrix ();
     glLoadIdentity ();
+
+    float screen_scale_inverse = 1.0 / display_info::screen_scale ();
+    vp[2] = octave::math::round (screen_scale_inverse *
+				 static_cast<float> (vp[2]));
+    vp[3] = octave::math::round (screen_scale_inverse *
+				 static_cast<float> (vp[3]));
     glOrtho (0, vp[2], vp[3], 0, xZ1, xZ2);
+
     glMatrixMode (GL_MODELVIEW);
     glPushMatrix ();
     glLoadIdentity ();
@@ -3705,10 +3719,12 @@
         // FIXME: actually add the code to do it!
       }
 
+
     if (i0 >= i1 || j0 >= j1)
       return;
 
-    glPixelZoom (pix_dx, -pix_dy);
+    glPixelZoom (display_info::screen_scale () * pix_dx,
+		 -display_info::screen_scale () * pix_dy);
     glRasterPos3d (im_xmin + nor_dx*j0, im_ymin + nor_dy*i0, 0);
 
     // by default this is 4
@@ -3818,7 +3834,10 @@
   {
 #if defined (HAVE_OPENGL)
 
-    glViewport (0, 0, w, h);
+    glViewport (0,
+		0,
+		display_info::screen_scale () * w,
+		display_info::screen_scale () * h);
 
 #else
 
@@ -3923,7 +3942,8 @@
     txt_renderer.set_font (props.get ("fontname").string_value (),
                            props.get ("fontweight").string_value (),
                            props.get ("fontangle").string_value (),
-                           props.get ("__fontsize_points__").double_value ());
+                           display_info::screen_scale () *
+			     props.get ("__fontsize_points__").double_value ());
   }
 
   void
@@ -4111,7 +4131,14 @@
     glMatrixMode (GL_PROJECTION);
     glPushMatrix ();
     glLoadIdentity ();
+
+    float screen_scale_inverse = 1.0 / display_info::screen_scale ();
+    vw[2] = octave::math::round (screen_scale_inverse *
+				static_cast<float> (vw[2]));
+    vw[3] = octave::math::round (screen_scale_inverse *
+				static_cast<float> (vw[3]));
     glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
+    
     glMatrixMode (GL_MODELVIEW);
     glPushMatrix ();
 
diff -r 6b3c78f84d3b libinterp/corefcn/graphics.cc
--- a/libinterp/corefcn/graphics.cc	Mon Jan 15 16:38:16 2018 -0500
+++ b/libinterp/corefcn/graphics.cc	Thu Jan 18 13:12:26 2018 -0800
@@ -6591,7 +6591,8 @@
   txt_renderer.set_font (get ("fontname").string_value (),
                          get ("fontweight").string_value (),
                          get ("fontangle").string_value (),
-                         get ("__fontsize_points__").double_value ());
+                         octave::display_info::screen_scale () *
+			   get ("__fontsize_points__").double_value ());
 }
 
 // The INTERNAL flag defines whether position or outerposition is used.
@@ -6686,7 +6687,7 @@
                   else if (text_rotation == 90. || text_rotation == 270.)
                     ignore_vertical = true;
                 }
-
+                                                                      
               if (! ignore_horizontal)
                 {
                   ext(0) = std::min (ext(0), text_pos(0)+text_ext(0));
@@ -8747,7 +8748,8 @@
   txt_renderer.set_font (get ("fontname").string_value (),
                          get ("fontweight").string_value (),
                          get ("fontangle").string_value (),
-                         get ("__fontsize_points__").double_value ());
+                         octave::display_info::screen_scale () *
+			   get ("__fontsize_points__").double_value ());
 
   txt_renderer.set_color (get_color_rgb ());
 }
