If you run the attached code 2 PDF files will be created. The surfaces are of different size because they go to different devices, but the second plot does not get properly re-scaled to fit its requested surface size. This is a trimmed down version of code I am using in my application but the goal is to build the data for a plot in one class and then re-use it with different plplot streams. In my code the first surface and stream are built with the xcairo driver and the second one with the extcairo driver holding a cairo pdf surface so that we can print to hardcopy the plot that is on the xcairo window. I am sure that I am missing something in my code but I can’t see what which is why I was inclined to think that a bug in the driver might be the culprit. As far as I can tell, the 2 plstreams should be independent and the extcairo window should scale to fit the surface…..

 

By the way, I only have access to a somewhat old linux system running plplot 5.9.7 and cairo 1.2.4.

 

Any suggestions or help are highly appreciated.

 

Thanks,

 

-Marco

 

#include <stdio.h>

#include <unistd.h>

#include <string>

#include <cmath>

#include <iostream>

#include <sstream>

#include <cairo.h>

#include <cairo-pdf.h>

 

#include <plplot.h>

#include <plstream.h>

 

plstream *NewStream(const std::string &outputDriver,

                    const std::string &geometry,

                    cairo_t *context = NULL)

{

   // Perform the plplot initialization required by your

   // task.

   plstream *pls = new plstream();

 

   // Re-size the device view surface to the size of the cairo window

   if(geometry != "")

   {

      pls->setopt("geometry", geometry.c_str());

   }

 

   pls->sdev(outputDriver.c_str());

 

   pls->init();

 

   if(context != NULL)

   {

      pls->cmd(PLESC_DEVINIT, context);

   }

 

   pls->adv(0);

 

   pls->vpor(0.1, 0.95, 0.15, 0.9);

 

 

   return(pls);

}

 

class Plot

{

   public:

 

      Plot()

      {

         for(int i = 0; i < 100; ++i)

         {

            xdata[i] = i * ((2.0 * M_PI) / 100.0);

            ydata[i] = sin(xdata[i]) * 100;

         }

      }

 

      void Init()

      {

         pls->clear();

         pls->col0(1);

         pls->wind(0.0, 2.0 * M_PI, -100.0, 100.0);

         pls->box("bcnst", 0.0, 0, "bcnstv", 0.0, 0);

         pls->col0(2);

         pls->box("g", 0.0, 0, "g", 0.0, 0);

         pls->sxax(6, 0);

         pls->syax(6, 0);

      }

 

      void Draw(int I)

      {

         PLFLT *x = xdata;

         PLFLT *y = ydata;

         pls->col0(4);

         pls->line(I, x, y);

 

         pls->flush();

      }

 

      plstream *pls;

      PLFLT xdata[100];

      PLFLT ydata[100];

 

};

 

int main( int argc, const char *argv[] )

{

 

   Plot plot;

 

   double pageW = 1152;

   double pageH = 528;

 

   std::stringstream geom;

   geom << pageW << "x" << pageH;

 

   cairo_surface_t *cs1 = cairo_pdf_surface_create("cairo1.pdf", pageW, pageH);

   cairo_t         *cairo1 = cairo_create(cs1);

   plstream *pls = NewStream("extcairo", geom.str(), cairo1);

   //plstream *pls = NewStream("xcairo", geom.str());

 

   plot.pls = pls;

   plot.Init();

   pls->col0(2);

   pls->lab("X axis", "Y axis", "Cairo 1");

 

   for(int i = 0; i < 100; ++i)

   {

      plot.Draw(i);

      usleep(10000);

   }

   pls->eop();

   cairo_show_page(cairo1);

   cairo_surface_flush(cs1);

   cairo_destroy(cairo1);

   cairo_surface_destroy(cs1);

 

 

   pageW = 11.0 * 72.0;

   pageH = 8.5 * 72.0;

 

   cairo_surface_t *cs2 = cairo_pdf_surface_create("cairo2.pdf", pageW, pageH);

   cairo_t         *cairo2 = cairo_create(cs2);

 

   plstream *pls2 = NewStream("extcairo", geom.str(), cairo2);

   //geom.str("");

   //geom << pageW << "x" << pageH;

   //plstream *pls2 = NewStream("xcairo", geom.str());

 

   plot.pls = pls2;

   plot.Init();

   pls2->col0(2);

   pls2->lab("X axis", "Y axis", "Cairo 2");

 

   for(int i = 0; i < 100; ++i)

   {

      plot.Draw(i);

   }

   pls2->eop();

 

   cairo_show_page(cairo2);

   cairo_surface_flush(cs2);

 

   cairo_destroy(cairo2);

   cairo_surface_destroy(cs2);

 

   delete pls;

   delete pls2;

 

   return(0);

}