# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1537171415 -7200
#      Mon Sep 17 10:03:35 2018 +0200
# Node ID 3837022180bcaa409eee2be859a72eb0ea5f3673
# Parent  4e108574385c161a1f1ac83cabeee9868b0b143a
[mq]: btndown

diff -r 4e108574385c -r 3837022180bc libgui/graphics/GLCanvas.cc
--- a/libgui/graphics/GLCanvas.cc	Sat Sep 15 09:43:48 2018 +0200
+++ b/libgui/graphics/GLCanvas.cc	Mon Sep 17 10:03:35 2018 +0200
@@ -75,6 +75,7 @@
         graphics_object fig = go.get_ancestor ("figure");
         double dpr = fig.get ("__device_pixel_ratio__").double_value ();
         m_renderer.set_viewport (dpr * width (), dpr * height ());
+        m_renderer.set_device_pixel_ratio (dpr);
         m_renderer.draw (go);
       }
   }
@@ -177,10 +178,8 @@
       {
         octave::opengl_selector s (m_glfcns);
 
-        graphics_object fig = ax.get_ancestor ("figure");
-        double dpr = fig.get ("__device_pixel_ratio__").double_value ();
-
-        s.set_viewport (dpr * width (), dpr * height ());
+        s.set_viewport (width (), height ());
+        m_renderer.set_device_pixel_ratio (1.0);
         return s.select (ax, pt.x (), height () - pt.y (),
                          octave::select_ignore_hittest);
       }
diff -r 4e108574385c -r 3837022180bc libinterp/corefcn/gl-render.cc
--- a/libinterp/corefcn/gl-render.cc	Sat Sep 15 09:43:48 2018 +0200
+++ b/libinterp/corefcn/gl-render.cc	Mon Sep 17 10:03:35 2018 +0200
@@ -613,12 +613,11 @@
 #endif
 
   opengl_renderer::opengl_renderer (opengl_functions& glfcns)
-    : m_glfcns (glfcns), toolkit (), xform (), xmin (), xmax (),
-      ymin (), ymax (), zmin (), zmax (), xZ1 (), xZ2 (),
+    : m_glfcns (glfcns), m_devpixratio (1.), toolkit (), xform (), xmin (),
+      xmax (), ymin (), ymax (), zmin (), zmax (), xZ1 (), xZ2 (),
       marker_id (), filled_marker_id (), camera_pos (), camera_dir (),
       view_vector (), interpreter ("none"), txt_renderer (),
-      m_current_light (0), m_max_lights (0), selecting (false),
-      m_devpixratio (1.)
+      m_current_light (0), m_max_lights (0), selecting (false)
   {
     // This constructor will fail if we don't have OpenGL or if the data
     // types we assumed in our public interface aren't compatible with the
@@ -702,10 +701,7 @@
 
   void
   opengl_renderer::draw_figure (const figure::properties& props)
-  {
-    // Current physical-pixel to toolkit-pixel factor
-    m_devpixratio = props.get___device_pixel_ratio__ ();
-    
+  {    
     // Initialize OpenGL context
     
     init_gl_context (props.is_graphicssmoothing (), props.get_color_rgb ());
@@ -1212,14 +1208,6 @@
     Matrix x_mat1 = props.get_opengl_matrix_1 ();
     Matrix x_mat2 = props.get_opengl_matrix_2 ();
 
-#if defined (HAVE_FRAMEWORK_OPENGL)
-    GLint vw[4];
-#else
-    int vw[4];
-#endif
-
-    m_glfcns.glGetIntegerv (GL_VIEWPORT, vw);
-
     m_glfcns.glMatrixMode (GL_MODELVIEW);
     m_glfcns.glLoadIdentity ();
     m_glfcns.glScaled (1, 1, -1);
@@ -1227,11 +1215,8 @@
     m_glfcns.glMatrixMode (GL_PROJECTION);
     m_glfcns.glLoadIdentity ();
 
-     // Use abstract Octave-pixels for transformation, not physical-pixels
-     vw[2] = octave::math::round (static_cast<float> (vw[2]) / m_devpixratio);
-     vw[3] = octave::math::round (static_cast<float> (vw[3]) / m_devpixratio);
-
-    m_glfcns.glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
+    Matrix vp = get_viewport ();
+    m_glfcns.glOrtho (0, vp(2), vp(3), 0, xZ1, xZ2);
     m_glfcns.glMultMatrixd (x_mat2.data ());
     m_glfcns.glMatrixMode (GL_MODELVIEW);
 
@@ -3678,28 +3663,18 @@
     if (bgcol.isempty () && ecol.isempty ())
       return;
 
-    Matrix pos = xform.scale (props.get_data_position ());
+    Matrix pos = props.get_data_position ();
     ColumnVector pixpos = get_transform ().transform (pos(0), pos(1),
-                                                      pos(2), false);
+                                                      pos(2), true);
     const Matrix bbox = props.get_extent_matrix ();
 
-#  if defined (HAVE_FRAMEWORK_OPENGL)
-    GLint vp[4];
-#  else
-    int vp[4];
-#  endif
-
-    m_glfcns.glGetIntegerv (GL_VIEWPORT, vp);
-
     // Save current transform matrices and set orthogonal window coordinates
     m_glfcns.glMatrixMode (GL_PROJECTION);
     m_glfcns.glPushMatrix ();
     m_glfcns.glLoadIdentity ();
 
-    vp[2] = octave::math::round (static_cast<float> (vp[2]) / m_devpixratio);
-    vp[3] = octave::math::round (static_cast<float> (vp[3]) / m_devpixratio);
-
-    m_glfcns.glOrtho (0, vp[2], vp[3], 0, xZ1, xZ2);
+    Matrix vp = get_viewport ();
+    m_glfcns.glOrtho (0, vp(2), vp(3), 0, xZ1, xZ2);
     m_glfcns.glMatrixMode (GL_MODELVIEW);
     m_glfcns.glPushMatrix ();
     m_glfcns.glLoadIdentity ();
@@ -3863,8 +3838,6 @@
       }
     else // clip to viewport
       {
-        GLfloat vp[4];
-        m_glfcns.glGetFloatv (GL_VIEWPORT, vp);
         // FIXME: actually add the code to do it!
       }
 
@@ -3997,6 +3970,35 @@
 #endif
   }
 
+  Matrix
+  opengl_renderer::get_viewport (void)
+  {
+    Matrix retval (1, 4, 0.0);
+    
+#if defined (HAVE_OPENGL)
+#if defined (HAVE_FRAMEWORK_OPENGL)
+    GLint vp[4];
+#else
+    int vp[4];
+#endif
+
+    m_glfcns.glGetIntegerv (GL_VIEWPORT, vp);
+
+    for (int i = 0; i < 4; i++)
+      retval(i) = static_cast<double> (vp[i]) / m_devpixratio;
+
+#else
+
+    // This shouldn't happen because construction of opengl_renderer
+    // objects is supposed to be impossible if OpenGL is not available.
+
+    panic_impossible ();
+
+#endif
+
+    return retval;
+  }
+
   void
   opengl_renderer::draw_pixels (int width, int height, const float *data)
   {
@@ -4264,23 +4266,12 @@
   opengl_renderer::init_marker (const std::string& m, double size, float width)
   {
 #if defined (HAVE_OPENGL)
-
-#  if defined (HAVE_FRAMEWORK_OPENGL)
-    GLint vw[4];
-#  else
-    int vw[4];
-#  endif
-
-    m_glfcns.glGetIntegerv (GL_VIEWPORT, vw);
-
     m_glfcns.glMatrixMode (GL_PROJECTION);
     m_glfcns.glPushMatrix ();
     m_glfcns.glLoadIdentity ();
 
-    vw[2] = octave::math::round (static_cast<float> (vw[2]) / m_devpixratio);
-    vw[3] = octave::math::round (static_cast<float> (vw[3]) / m_devpixratio);
-
-    m_glfcns.glOrtho (0, vw[2], vw[3], 0, xZ1, xZ2);
+    Matrix vp = get_viewport ();
+    m_glfcns.glOrtho (0, vp(2), vp(3), 0, xZ1, xZ2);
     m_glfcns.glMatrixMode (GL_MODELVIEW);
     m_glfcns.glPushMatrix ();
 
diff -r 4e108574385c -r 3837022180bc libinterp/corefcn/gl-render.h
--- a/libinterp/corefcn/gl-render.h	Sat Sep 15 09:43:48 2018 +0200
+++ b/libinterp/corefcn/gl-render.h	Mon Sep 17 10:03:35 2018 +0200
@@ -65,6 +65,8 @@
     }
 
     virtual void set_viewport (int w, int h);
+    virtual Matrix get_viewport (void);
+    virtual void set_device_pixel_ratio (double dpr) { m_devpixratio = dpr; }
     virtual graphics_xform get_transform (void) const { return xform; }
     virtual uint8NDArray get_pixels (int width, int height);
 
@@ -210,6 +212,9 @@
   protected:
 
     opengl_functions& m_glfcns;
+    
+    // Factor used for translating Octave pixels to actual device pixels
+    double m_devpixratio;
 
   private:
 
@@ -245,8 +250,6 @@
     // Indicate we are drawing for selection purpose
     bool selecting;
 
-    // Factor used for translating Octave pixels to actual device pixels
-    double m_devpixratio;
   private:
     class patch_tesselator;
   };
diff -r 4e108574385c -r 3837022180bc libinterp/corefcn/gl2ps-print.cc
--- a/libinterp/corefcn/gl2ps-print.cc	Sat Sep 15 09:43:48 2018 +0200
+++ b/libinterp/corefcn/gl2ps-print.cc	Mon Sep 17 10:03:35 2018 +0200
@@ -413,6 +413,9 @@
             Matrix c = fprop.get_color_rgb ();
             m_glfcns.glClearColor (c(0), c(1), c(2), 1);
 
+            // Allow figures to be printed at arbitrary resolution
+            set_device_pixel_ratio (fprop.get___device_pixel_ratio__ ());
+
             // GL2PS_SILENT was removed to allow gl2ps to print errors on stderr
             GLint ret = gl2psBeginPage ("gl2ps_renderer figure", "Octave",
                                         nullptr, gl2ps_term, gl2ps_sort,
