Hi,
In our application we draw a graph using an extcairo device. While
testing on a 32 bit system I ran in an issue. When zooming in on a graph
the cairo context got the status CAIRO_STATUS_INVALID_MATRIX.
Reproducing the issue pointed to the function plP_wcpcx. The function
returned a PLINT_MIN due to a the double result being too large. (It is
implementation defined whether C returns the largest or the smallest
value in this case.) This caused an 'a' of 0, which was where cairo got
its CAIRO_STATUS_INVALID_MATRIX status. This issue was caused by circles
drawn outside the clipping area of the plot.
The issue occurs both with plplot 5.10.0 as shipped with Debian Strech
and the current git master.
I created a small patch which seems to fix the issue for me. It simply
does not draw the arcs that are fully outside the clipping area. I'm not
entirely sure whether this is the right solution, but it fixes the issue
for me. The patch contains a debug printf for testing purposes. I
modified example 3 to reproduce the issue. The x value becomes PLINT_MIN
on a 32 bit system. The output of x03 on the console with the plarc
patch applied is:
xscl[0] 2144687274, xscl[1] 2145210464
xscl[0] -2147483648, xscl[1] -2147483648
Is this patch the right approach?
Regards,
Mark de Wever
diff --git a/src/plarc.c b/src/plarc.c
index 25defdf9a..d3034a94a 100644
--- a/src/plarc.c
+++ b/src/plarc.c
@@ -147,14 +147,20 @@ c_plarc( PLFLT x, PLFLT y, PLFLT a, PLFLT b, PLFLT
angle1, PLFLT angle2, PLFLT r
// TODO: For now, only unrotated plots use the driver-accelerated path.
if ( plsc->dev_arc && plsc->diorot == 0 )
{
- arc_info = (arc_struct *) malloc( (size_t) sizeof ( arc_struct ) );
-
xscl[0] = plP_wcpcx( x - a );
xscl[1] = plP_wcpcx( x + a );
yscl[0] = plP_wcpcy( y - b );
yscl[1] = plP_wcpcy( y + b );
+ printf("xscl[0] %i, xscl[1] %i\n", xscl[0], xscl[1]);
+ if ( xscl[0] > plsc->clpxma || xscl[1] < plsc->clpxmi || yscl[0] >
plsc->clpyma || yscl[1] < plsc->clpymi )
+ {
+ return;
+ }
+
difilt( xscl, yscl, 2, &clpxmi, &clpxma, &clpymi, &clpyma );
+ arc_info = (arc_struct *) malloc( (size_t) sizeof ( arc_struct ) );
+
arc_info->x = 0.5 * ( xscl[1] + xscl[0] );
arc_info->y = 0.5 * ( yscl[1] + yscl[0] );
arc_info->a = 0.5 * ( xscl[1] - xscl[0] );
// Polar plot demo.
//
#include "plcdemos.h"
//--------------------------------------------------------------------------
// main
//
// Generates polar plot, with 1-1 scaling.
//--------------------------------------------------------------------------
int
main( int argc, char *argv[] )
{
int i;
PLFLT dtr, theta, dx, dy, r, offset;
char text[4];
static PLFLT x0[361], y0[361];
static PLFLT x[361], y[361];
dtr = M_PI / 180.0;
for ( i = 0; i <= 360; i++ )
{
x0[i] = cos( dtr * i );
y0[i] = sin( dtr * i );
}
// Parse and process command line arguments
(void) plparseopts( &argc, argv, PL_PARSE_FULL );
// Initialize plplot
plinit();
// Set up viewport and window, but do not draw box
plenv( - 1.3, 1.3, -1.3, 1.3, 1, -2 );
// Draw circles for polar grid
plarc( 2.96e5 , 0.0, 0.1 * i, 0.1 * i, 0.0, 360.0, 0.0, 0 );
plarc( 3e5 , 0.0, 1, 1, 0.0, 360.0, 0.0, 0 );
plend();
exit( 0 );
}
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel