PLplot  5.15.0
plbuf.c
Go to the documentation of this file.
1 // Handle plot buffer.
2 //
3 // Copyright (C) 1992 Maurice LeBrun
4 // Copyright (C) 2004-2015 Alan W. Irwin
5 // Copyright (C) 2005 Thomas J. Duck
6 // Copyright (C) 2006 Jim Dishaw
7 //
8 // This file is part of PLplot.
9 //
10 // PLplot is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Library General Public License as published
12 // by the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14 //
15 // PLplot is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Library General Public License for more details.
19 //
20 // You should have received a copy of the GNU Library General Public License
21 // along with PLplot; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 
25 #define NEED_PLDEBUG
26 #include "plplotP.h"
27 #include "drivers.h"
28 #include "metadefs.h"
29 
30 #include <string.h>
31 
32 #if defined ( _MSC_VER ) && _MSC_VER <= 1500
33 // Older versions of Visual Studio (2005 perhaps 2008) do not define uint8_t
34 // The newer versions of Visual Studio will not install on Vista or older
35 // versions of Windows.
36 typedef unsigned char uint8_t;
37 typedef unsigned short int uint16_t;
38 #endif
39 
40 //
41 // Function prototypes
42 //
43 
44 // Public
45 void * plbuf_save( PLStream *pls, void *state );
46 
47 // Private
48 static void check_buffer_size( PLStream *pls, size_t data_size );
49 
50 static int rd_command( PLStream *pls, U_CHAR *p_c );
51 static void rd_data( PLStream *pls, void *buf, size_t buf_size );
52 static void rd_data_no_copy( PLStream *pls, void **buf, size_t buf_size );
53 
54 static void wr_command( PLStream *pls, U_CHAR c );
55 static void wr_data( PLStream *pls, void *buf, size_t buf_size );
56 
57 static void plbuf_control( PLStream *pls, U_CHAR c );
58 static void plbuf_fill( PLStream *pls );
59 static void plbuf_swin( PLStream *pls, PLWindow *plwin );
60 
61 static void rdbuf_init( PLStream *pls );
62 static void rdbuf_line( PLStream *pls );
63 static void rdbuf_polyline( PLStream *pls );
64 static void rdbuf_eop( PLStream *pls );
65 static void rdbuf_bop( PLStream *pls );
66 static void rdbuf_state( PLStream *pls );
67 static void rdbuf_esc( PLStream *pls );
68 static void rdbuf_image( PLStream *pls );
69 static void rdbuf_text( PLStream *pls );
70 static void rdbuf_text_unicode( PLINT op, PLStream *pls );
71 static void rdbuf_fill( PLStream *pls );
72 static void rdbuf_clip( PLStream *pls );
73 static void rdbuf_swin( PLStream *pls );
74 static void rdbuf_di( PLStream *pls );
75 static void rdbuf_setsub( PLStream *pls );
76 static void rdbuf_ssub( PLStream *pls );
77 
78 //--------------------------------------------------------------------------
79 // Plplot internal interface to the plot buffer
80 //--------------------------------------------------------------------------
81 
82 //--------------------------------------------------------------------------
83 // plbuf_init()
84 //
85 // Initialize device.
86 //--------------------------------------------------------------------------
87 
88 void
90 {
91  dbug_enter( "plbuf_init" );
92 
93  // Indicate that this buffer is not being read
94  pls->plbuf_read = FALSE;
95 
96  if ( pls->plbuf_buffer == NULL )
97  {
98  // We have not allocated a buffer, so do it now
99  pls->plbuf_buffer_grow = 128 * 1024;
100 
101  if ( ( pls->plbuf_buffer = malloc( pls->plbuf_buffer_grow ) ) == NULL )
102  plexit( "plbuf_init: Error allocating plot buffer." );
103 
105  pls->plbuf_top = 0;
106  pls->plbuf_readpos = 0;
107  }
108  else
109  {
110  // Buffer is allocated, move the top to the beginning
111  pls->plbuf_top = 0;
112  }
113 }
114 
115 //--------------------------------------------------------------------------
116 // plbuf_eop()
117 //
118 // End of page.
119 //--------------------------------------------------------------------------
120 
121 void
123 {
124  dbug_enter( "plbuf_eop" );
125 
126  wr_command( pls, (U_CHAR) EOP );
127 }
128 
129 //--------------------------------------------------------------------------
130 // plbuf_bop()
131 //
132 // Set up for the next page.
133 // To avoid problems redisplaying partially filled pages, on each BOP the
134 // old data in the buffer is ignored by setting the top back to the
135 // beginning of the buffer.
136 //
137 // Also write state information to ensure the next page is correct.
138 //--------------------------------------------------------------------------
139 
140 void
142 {
143  dbug_enter( "plbuf_bop" );
144 
145  plbuf_tidy( pls );
146 
147  // Move the top to the beginning
148  pls->plbuf_top = 0;
149 
150  wr_command( pls, (U_CHAR) BOP );
151 
152  // Save the current configuration (e.g. colormap, current colors) to
153  // allow plRemakePlot to correctly regenerate the plot
154 
155  // Save the current colors. Do not use the PLSTATE_* commands
156  // because the color might have already been set by the driver
157  // during initialization and this would result in an extraneous
158  // color command being sent. The goal is to preserve the current
159  // color state so that rdbuf_bop can restore it. This needs
160  // to occur immediately after the BOP command so that it can be
161  // read by rdbuf_bop.
162  wr_data( pls, &( pls->icol0 ), sizeof ( pls->icol0 ) );
163  wr_data( pls, &( pls->icol1 ), sizeof ( pls->icol1 ) );
164  wr_data( pls, &( pls->curcolor ), sizeof ( pls->curcolor ) );
165  wr_data( pls, &( pls->curcmap ), sizeof ( pls->curcmap ) );
166  wr_data( pls, &pls->nsubx, sizeof ( pls->nsubx ) );
167  wr_data( pls, &pls->nsuby, sizeof ( pls->nsuby ) );
168 
169  // Save all the other state parameters via the plbuf_state function
170  plbuf_state( pls, PLSTATE_CMAP0 );
171  plbuf_state( pls, PLSTATE_CMAP1 );
172  plbuf_state( pls, PLSTATE_WIDTH );
173  plbuf_state( pls, PLSTATE_FILL );
174  plbuf_state( pls, PLSTATE_CHR );
175  plbuf_state( pls, PLSTATE_SYM );
176  plbuf_state( pls, PLSTATE_EOFILL );
177 
178  //pls->difilt may also be set pre plinit() and is used
179  //in plbop for text scaling.
180  wr_data( pls, &pls->difilt, sizeof ( pls->difilt ) );
181 }
182 
183 //--------------------------------------------------------------------------
184 //
185 // plbuf_setsub()
186 //
187 // Set the subpage. Required to carry out commands which apply to just one
188 // sub page such as plclear
189 //--------------------------------------------------------------------------
190 
191 void
193 {
194  dbug_enter( "plbuf_setsub" );
195 
196  wr_command( pls, (U_CHAR) SETSUB );
197  wr_data( pls, &pls->cursub, sizeof ( pls->cursub ) );
198 }
199 
200 //--------------------------------------------------------------------------
201 //
202 // plbuf_ssub()
203 //
204 // Set the number of subpages. Required to carry out commands which apply to
205 // just one sub page such as plclear
206 //--------------------------------------------------------------------------
207 
208 void
210 {
211  dbug_enter( "plbuf_setsub" );
212 
213  wr_command( pls, (U_CHAR) SSUB );
214  wr_data( pls, &pls->nsubx, sizeof ( pls->nsubx ) );
215  wr_data( pls, &pls->nsuby, sizeof ( pls->nsuby ) );
216 }
217 
218 //--------------------------------------------------------------------------
219 // plbuf_tidy()
220 //
221 // Close graphics file
222 //--------------------------------------------------------------------------
223 
224 void
226 {
227  dbug_enter( "plbuf_tidy" );
228 }
229 
230 //--------------------------------------------------------------------------
231 // plbuf_line()
232 //
233 // Draw a line in the current color from (x1,y1) to (x2,y2).
234 //--------------------------------------------------------------------------
235 
236 void
237 plbuf_line( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
238 {
239  short xpl[2], ypl[2];
240 
241  dbug_enter( "plbuf_line" );
242 
243  wr_command( pls, (U_CHAR) LINE );
244 
245  xpl[0] = x1a;
246  xpl[1] = x2a;
247  ypl[0] = y1a;
248  ypl[1] = y2a;
249 
250  //store the clipping information first
251  //wr_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
252 // wr_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
253 // wr_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
254 // wr_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
255 
256  //then the line data
257  wr_data( pls, xpl, sizeof ( short ) * 2 );
258  wr_data( pls, ypl, sizeof ( short ) * 2 );
259 }
260 
261 //--------------------------------------------------------------------------
262 // plbuf_polyline()
263 //
264 // Draw a polyline in the current color.
265 //--------------------------------------------------------------------------
266 
267 void
268 plbuf_polyline( PLStream *pls, short *xa, short *ya, PLINT npts )
269 {
270  dbug_enter( "plbuf_polyline" );
271 
272  wr_command( pls, (U_CHAR) POLYLINE );
273 
274  //store the clipping information first
275  //wr_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
276 // wr_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
277 // wr_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
278 // wr_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
279 
280  //then the number of points
281  wr_data( pls, &npts, sizeof ( PLINT ) );
282 
283  //then the point data
284  wr_data( pls, xa, sizeof ( short ) * (size_t) npts );
285  wr_data( pls, ya, sizeof ( short ) * (size_t) npts );
286 }
287 
288 //--------------------------------------------------------------------------
289 // plbuf_state()
290 //
291 // Handle change in PLStream state (color, pen width, fill attribute, etc).
292 //--------------------------------------------------------------------------
293 
294 void
296 {
297  dbug_enter( "plbuf_state" );
298 
299  wr_command( pls, (U_CHAR) CHANGE_STATE );
300  wr_command( pls, (U_CHAR) op );
301 
302  switch ( op )
303  {
304  case PLSTATE_WIDTH:
305  wr_data( pls, &( pls->width ), sizeof ( pls->width ) );
306  break;
307 
308  case PLSTATE_COLOR0:
309  wr_data( pls, &( pls->icol0 ), sizeof ( pls->icol0 ) );
310  if ( pls->icol0 == PL_RGB_COLOR )
311  {
312  wr_data( pls, &( pls->curcolor.r ), sizeof ( pls->curcolor.r ) );
313  wr_data( pls, &( pls->curcolor.g ), sizeof ( pls->curcolor.g ) );
314  wr_data( pls, &( pls->curcolor.b ), sizeof ( pls->curcolor.b ) );
315  wr_data( pls, &( pls->curcolor.a ), sizeof ( pls->curcolor.a ) );
316  }
317  break;
318 
319  case PLSTATE_COLOR1:
320  wr_data( pls, &( pls->icol1 ), sizeof ( pls->icol1 ) );
321  break;
322 
323  case PLSTATE_FILL:
324  wr_data( pls, &( pls->patt ), sizeof ( pls->patt ) );
325  wr_data( pls, &( pls->nps ), sizeof ( pls->nps ) );
326  wr_data( pls, &( pls->inclin[0] ), sizeof ( pls->inclin ) );
327  wr_data( pls, &( pls->delta[0] ), sizeof ( pls->delta ) );
328  break;
329 
330  case PLSTATE_CMAP0:
331  // Save the number of colors in the palatte
332  wr_data( pls, &( pls->ncol0 ), sizeof ( pls->ncol0 ) );
333  // Save the color palatte
334  wr_data( pls, &( pls->cmap0[0] ), sizeof ( PLColor ) * pls->ncol0 );
335  break;
336 
337  case PLSTATE_CMAP1:
338  // Save the number of colors in the palatte
339  wr_data( pls, &( pls->ncol1 ), sizeof ( pls->ncol1 ) );
340  // Save the color palatte
341  wr_data( pls, &( pls->cmap1[0] ), sizeof ( PLColor ) * pls->ncol1 );
342  break;
343 
344  case PLSTATE_CHR:
345  //save the chrdef and chrht parameters
346  wr_data( pls, &( pls->chrdef ), sizeof ( pls->chrdef ) );
347  wr_data( pls, &( pls->chrht ), sizeof ( pls->chrht ) );
348  break;
349 
350  case PLSTATE_SYM:
351  //save the symdef and symht parameters
352  wr_data( pls, &( pls->symdef ), sizeof ( pls->symdef ) );
353  wr_data( pls, &( pls->symht ), sizeof ( pls->symht ) );
354  break;
355  case PLSTATE_EOFILL:
356  //As far as I can see this is only possible as a one way change
357  //setting PLStream::dev_eofill to 1. However, in case this
358  //behaviour changes in the future we may as well store the value
359  wr_data( pls, &( pls->dev_eofill ), sizeof ( pls->dev_eofill ) );
360  break;
361  }
362 }
363 
364 
365 //--------------------------------------------------------------------------
366 // plbuf_image()
367 //
368 // write image described in points pls->dev_x[], pls->dev_y[], pls->dev_z[].
369 // pls->nptsX, pls->nptsY.
370 //--------------------------------------------------------------------------
371 
372 static void
374 {
375  PLINT npts = pls->dev_nptsX * pls->dev_nptsY;
376 
377  dbug_enter( "plbuf_image" );
378 
379  wr_data( pls, &pls->dev_nptsX, sizeof ( PLINT ) );
380  wr_data( pls, &pls->dev_nptsY, sizeof ( PLINT ) );
381 
382  wr_data( pls, &img_dt->xmin, sizeof ( PLFLT ) );
383  wr_data( pls, &img_dt->ymin, sizeof ( PLFLT ) );
384  wr_data( pls, &img_dt->dx, sizeof ( PLFLT ) );
385  wr_data( pls, &img_dt->dy, sizeof ( PLFLT ) );
386 
387  wr_data( pls, &pls->dev_zmin, sizeof ( short ) );
388  wr_data( pls, &pls->dev_zmax, sizeof ( short ) );
389 
390  wr_data( pls, pls->dev_ix, sizeof ( short ) * (size_t) npts );
391  wr_data( pls, pls->dev_iy, sizeof ( short ) * (size_t) npts );
392  wr_data( pls, pls->dev_z,
393  sizeof ( unsigned short )
394  * (size_t) ( ( pls->dev_nptsX - 1 ) * ( pls->dev_nptsY - 1 ) ) );
395 }
396 
397 //--------------------------------------------------------------------------
398 // plbuf_text()
399 //
400 // Handle text call.
401 //--------------------------------------------------------------------------
402 
403 static void
405 {
406  dbug_enter( "plbuf_text" );
407 
408  // Check for missing data.
409  if ( text == NULL )
410  return;
411 
412  // Store the state information needed to render the text
413 
414  wr_data( pls, &pls->chrht, sizeof ( pls->chrht ) );
415  wr_data( pls, &pls->diorot, sizeof ( pls->diorot ) );
416  //wr_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
417 // wr_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
418 // wr_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
419 // wr_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
420 
421  // Store the text layout information
422 
423  wr_data( pls, &text->base, sizeof ( text->base ) );
424  wr_data( pls, &text->just, sizeof ( text->just ) );
425  wr_data( pls, text->xform, sizeof ( text->xform[0] ) * 4 );
426  wr_data( pls, &text->x, sizeof ( text->x ) );
427  wr_data( pls, &text->y, sizeof ( text->y ) );
428  wr_data( pls, &text->refx, sizeof ( text->refx ) );
429  wr_data( pls, &text->refy, sizeof ( text->refy ) );
430  wr_data( pls, &text->font_face, sizeof ( text->font_face ) );
431 
432  // Store the text
433 
434  if ( pls->dev_unicode )
435  {
436  PLUNICODE fci;
437 
438  // Retrieve and store the font characterization integer
439  plgfci( &fci );
440 
441  wr_data( pls, &fci, sizeof ( fci ) );
442 
443  wr_data( pls, &text->unicode_array_len, sizeof ( U_SHORT ) );
444  if ( text->unicode_array_len )
445  wr_data( pls,
446  text->unicode_array,
447  sizeof ( PLUNICODE ) * text->unicode_array_len );
448  }
449  else
450  {
451  U_SHORT len;
452 
453  // len + 1 to copy the NUL termination
454  len = strlen( text->string ) + 1;
455  wr_data( pls, &len, sizeof ( len ) );
456  if ( len > 0 )
457  wr_data( pls, (void *) text->string, sizeof ( char ) * len );
458  }
459 }
460 
461 //--------------------------------------------------------------------------
462 // plbuf_text_unicode()
463 //
464 // Handle text buffering for the new unicode pathway.
465 //--------------------------------------------------------------------------
466 
467 static void
469 {
470  PLUNICODE fci;
471 
472  dbug_enter( "plbuf_text_unicode" );
473 }
474 
475 
476 //--------------------------------------------------------------------------
477 // plbuf_esc()
478 //
479 // Escape function. Note that any data written must be in device
480 // independent form to maintain the transportability of the metafile.
481 //
482 // Functions:
483 //
484 // PLESC_FILL Fill polygon
485 // PLESC_SWIN Set plot window parameters
486 // PLESC_IMAGE Draw image
487 // PLESC_HAS_TEXT Draw PostScript text
488 // PLESC_CLEAR Clear Background
489 // PLESC_START_RASTERIZE
490 // PLESC_END_RASTERIZE Start and stop rasterization
491 //--------------------------------------------------------------------------
492 
493 void
494 plbuf_esc( PLStream *pls, PLINT op, void *ptr )
495 {
496  plbuffer *buffer;
497  dbug_enter( "plbuf_esc" );
498 
499  wr_command( pls, (U_CHAR) ESCAPE );
500  wr_command( pls, (U_CHAR) op );
501 
502  switch ( op )
503  {
504  case PLESC_FILL:
505  plbuf_fill( pls );
506  break;
507 
508  case PLESC_SWIN:
509  plbuf_swin( pls, (PLWindow *) ptr );
510  break;
511 
512  case PLESC_IMAGE:
513  plbuf_image( pls, (IMG_DT *) ptr );
514  break;
515 
516  // Unicode and non-Unicode text handling
517  case PLESC_HAS_TEXT:
518  plbuf_text( pls, (EscText *) ptr );
519  break;
520 
521  // Alternate Unicode text handling
522  case PLESC_BEGIN_TEXT:
523  case PLESC_TEXT_CHAR:
524  case PLESC_CONTROL_CHAR:
525  case PLESC_END_TEXT:
526  // The alternative unicode processing is not correctly implemented
527  // and is currently only used by Cairo, which handles its own
528  // redraws. Skip further processing for now
529 
530  //plbuf_text_unicode( pls, (EscText *) ptr );
531  break;
532 
533  case PLESC_IMPORT_BUFFER:
534  {
535  size_t extraSize;
536  buffer = (plbuffer *) ptr;
537  extraSize = buffer->size > pls->plbuf_top ? buffer->size - pls->plbuf_top : 0;
538  check_buffer_size( pls, extraSize );
539  memcpy( pls->plbuf_buffer, buffer->buffer, buffer->size );
540  pls->plbuf_top = buffer->size;
541  break;
542  }
543 
544  case PLESC_APPEND_BUFFER:
545  buffer = (plbuffer *) ptr;
546  check_buffer_size( pls, buffer->size );
547  memcpy( (char *) ( pls->plbuf_buffer ) + pls->plbuf_top, buffer->buffer, buffer->size );
548  pls->plbuf_top += buffer->size;
549  break;
550 
552  plFlushBuffer( pls, FALSE, (size_t) ( -1 ) );
553  break;
554 
555 #if 0
556  // These are a no-op. They just need an entry in the buffer.
557  case PLESC_CLEAR:
559  case PLESC_END_RASTERIZE:
560  break;
561 #endif
562  }
563 }
564 
565 //--------------------------------------------------------------------------
566 // plbuf_di()
567 //
568 // Driver interface function. Saves all info needed for a call to pldi_ini()
569 // e.g.orientation etc.
570 //--------------------------------------------------------------------------
572 {
574 
575  wr_data( pls, &pls->difilt, sizeof ( pls->difilt ) );
576  wr_data( pls, &pls->dipxmin, sizeof ( pls->dipxmin ) );
577  wr_data( pls, &pls->dipymin, sizeof ( pls->dipymin ) );
578  wr_data( pls, &pls->dipxmax, sizeof ( pls->dipxmax ) );
579  wr_data( pls, &pls->dipymax, sizeof ( pls->dipymax ) );
580  wr_data( pls, &pls->aspect, sizeof ( pls->aspect ) );
581  wr_data( pls, &pls->mar, sizeof ( pls->mar ) );
582  wr_data( pls, &pls->jx, sizeof ( pls->jx ) );
583  wr_data( pls, &pls->jy, sizeof ( pls->jy ) );
584  wr_data( pls, &pls->diorot, sizeof ( pls->diorot ) );
585  wr_data( pls, &pls->dimxmin, sizeof ( pls->dimxmin ) );
586  wr_data( pls, &pls->dimymin, sizeof ( pls->dimymin ) );
587  wr_data( pls, &pls->dimxmax, sizeof ( pls->dimxmax ) );
588  wr_data( pls, &pls->dimymax, sizeof ( pls->dimymax ) );
589  wr_data( pls, &pls->dimxpmm, sizeof ( pls->dimxpmm ) );
590  wr_data( pls, &pls->dimypmm, sizeof ( pls->dimypmm ) );
591 }
592 
593 //--------------------------------------------------------------------------
594 // plbuf_fill()
595 //
596 // Fill polygon described in points pls->dev_x[] and pls->dev_y[].
597 //--------------------------------------------------------------------------
598 
599 static void
601 {
602  dbug_enter( "plbuf_fill" );
603 
604  wr_data( pls, &pls->dev_npts, sizeof ( PLINT ) );
605  wr_data( pls, pls->dev_x, sizeof ( short ) * (size_t) pls->dev_npts );
606  wr_data( pls, pls->dev_y, sizeof ( short ) * (size_t) pls->dev_npts );
607 }
608 
609 //--------------------------------------------------------------------------
610 // plbuf_clip
611 //
612 // Set the clipping limits
613 //--------------------------------------------------------------------------
614 void
616 {
617  dbug_enter( "plbuf_clip" );
618 
619  wr_command( pls, (U_CHAR) CLIP );
620 
621  wr_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
622  wr_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
623  wr_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
624  wr_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
625 }
626 
627 //--------------------------------------------------------------------------
628 // plbuf_swin()
629 //
630 // Set up plot window parameters.
631 //--------------------------------------------------------------------------
632 
633 static void
635 {
636  dbug_enter( "plbuf_swin" );
637 
638  wr_data( pls, &plwin->dxmi, sizeof ( plwin->dxmi ) );
639  wr_data( pls, &plwin->dxma, sizeof ( plwin->dxma ) );
640  wr_data( pls, &plwin->dymi, sizeof ( plwin->dymi ) );
641  wr_data( pls, &plwin->dyma, sizeof ( plwin->dyma ) );
642 
643  wr_data( pls, &plwin->wxmi, sizeof ( plwin->wxmi ) );
644  wr_data( pls, &plwin->wxma, sizeof ( plwin->wxma ) );
645  wr_data( pls, &plwin->wymi, sizeof ( plwin->wymi ) );
646  wr_data( pls, &plwin->wyma, sizeof ( plwin->wyma ) );
647 }
648 
649 //--------------------------------------------------------------------------
650 // Routines to read from & process the plot buffer.
651 //--------------------------------------------------------------------------
652 
653 //--------------------------------------------------------------------------
654 // plbuf_write()
655 //
656 // Provides an interface for other parts of PLplot (e.g. plmetafile.c) to
657 // write into the buffer. The reason why wr_command and wr_data are not
658 // exposed is to help the optimizer to inline those two functions.
659 //--------------------------------------------------------------------------
660 void plbuf_write( PLStream *pls, void *data, size_t bytes )
661 {
662  wr_data( pls, data, bytes );
663 }
664 
665 //--------------------------------------------------------------------------
666 // rdbuf_init()
667 //
668 // Initialize device.
669 //--------------------------------------------------------------------------
670 
671 static void
673 {
674  dbug_enter( "rdbuf_init" );
675 }
676 
677 //--------------------------------------------------------------------------
678 // rdbuf_eop()
679 //
680 // End of page.
681 //--------------------------------------------------------------------------
682 
683 static void
685 {
686  dbug_enter( "rdbuf_eop" );
687 }
688 
689 //--------------------------------------------------------------------------
690 // rdbuf_bop()
691 //
692 // Set up for the next page.
693 //--------------------------------------------------------------------------
694 
695 static void
697 {
698  U_CHAR cmd = 0;
699  int nRead;
700 
701  dbug_enter( "rdbuf_bop" );
702 
703  pls->nplwin = 0;
704 
705  // Read the current color state from the plot buffer
706  rd_data( pls, &( pls->icol0 ), sizeof ( pls->icol0 ) );
707  rd_data( pls, &( pls->icol1 ), sizeof ( pls->icol1 ) );
708  rd_data( pls, &( pls->curcolor ), sizeof ( pls->curcolor ) );
709  rd_data( pls, &( pls->curcmap ), sizeof ( pls->curcmap ) );
710  rd_data( pls, &( pls->nsubx ), sizeof ( pls->nsubx ) );
711  rd_data( pls, &( pls->nsuby ), sizeof ( pls->nsuby ) );
712 
713  // We need to read the colormaps that were stored by plbuf_bop
714  // now because when plP_state is used to set the color, a wrong
715  // colormap will be used if it was changed.
716 
717  // Read the command (should be CHANGE_STATE PLSTATE_CMAP0)
718  nRead = rd_command( pls, &cmd );
719  if ( nRead == 0 || cmd != CHANGE_STATE )
720  {
721  plabort( "rdbuf_bop: Error reading first change state" );
722  return;
723  }
724  plbuf_control( pls, cmd );
725 
726  // Read the command (should be CHANGE_STATE PLSTATE_CMAP1)
727  nRead = rd_command( pls, &cmd );
728  if ( nRead == 0 || cmd != CHANGE_STATE )
729  {
730  plabort( "rdbuf_bop: Error reading second change state" );
731  return;
732  }
733  plbuf_control( pls, cmd );
734 
735  // Read the command (should be CHANGE_STATE PLSTATE_WIDTH)
736  nRead = rd_command( pls, &cmd );
737  if ( nRead == 0 || cmd != CHANGE_STATE )
738  {
739  plabort( "rdbuf_bop: Error reading third change state" );
740  return;
741  }
742  plbuf_control( pls, cmd );
743 
744  // Read the command (should be CHANGE_STATE PLSTATE_FILL)
745  nRead = rd_command( pls, &cmd );
746  if ( nRead == 0 || cmd != CHANGE_STATE )
747  {
748  plabort( "rdbuf_bop: Error reading fourth change state" );
749  return;
750  }
751  plbuf_control( pls, cmd );
752 
753  // Read the command (should be CHANGE_STATE PLSTATE_CHR)
754  nRead = rd_command( pls, &cmd );
755  if ( nRead == 0 || cmd != CHANGE_STATE )
756  {
757  plabort( "rdbuf_bop: Error reading fifth change state" );
758  return;
759  }
760  plbuf_control( pls, cmd );
761 
762  // Read the command (should be CHANGE_STATE PLSTATE_SYM)
763  nRead = rd_command( pls, &cmd );
764  if ( nRead == 0 || cmd != CHANGE_STATE )
765  {
766  plabort( "rdbuf_bop: Error reading sixth change state" );
767  return;
768  }
769  plbuf_control( pls, cmd );
770 
771  // Read the command (should be CHANGE_STATE PLSTATE_EOFILL)
772  nRead = rd_command( pls, &cmd );
773  if ( nRead == 0 || cmd != CHANGE_STATE )
774  {
775  plabort( "rdbuf_bop: Error reading seventh change state" );
776  return;
777  }
778  plbuf_control( pls, cmd );
779 
780  // and now we can set the color
781  if ( pls->curcmap == 0 )
782  {
784  }
785  else
786  {
788  }
789 
790  //read DI
791  rd_data( pls, &( pls->difilt ), sizeof ( pls->difilt ) );
792 
793  plP_bop();
794 }
795 
796 //--------------------------------------------------------------------------
797 // rdbuf_setsub()
798 //
799 // set the subpage
800 //--------------------------------------------------------------------------
801 
802 static void
804 {
805  rd_data( pls, (void *) ( &pls->cursub ), sizeof ( pls->cursub ) );
806  plP_setsub();
807 }
808 
809 //--------------------------------------------------------------------------
810 // rdbuf_ssub()
811 //
812 // set the subpage number of subpages
813 //--------------------------------------------------------------------------
814 
815 static void
817 {
818  rd_data( pls, (void *) ( &pls->nsubx ), sizeof ( pls->nsubx ) );
819  rd_data( pls, (void *) ( &pls->nsuby ), sizeof ( pls->nsuby ) );
820  c_plssub( pls->nsubx, pls->nsuby );
821 }
822 
823 //--------------------------------------------------------------------------
824 // rdbuf_line()
825 //
826 // Draw a line in the current color from (x1,y1) to (x2,y2).
827 //--------------------------------------------------------------------------
828 
829 static void
831 {
832  short *xpl, *ypl;
833  PLINT npts = 2;
834 
835  dbug_enter( "rdbuf_line" );
836 
837  //read the clipping data first
838  //rd_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
839 // rd_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
840 // rd_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
841 // rd_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
842 
843  //then the line data
844  // Use the "no copy" version because the endpoint data array does
845  // not need to persist outside of this function
846  rd_data_no_copy( pls, (void **) &xpl, sizeof ( short ) * (size_t) npts );
847  rd_data_no_copy( pls, (void **) &ypl, sizeof ( short ) * (size_t) npts );
848 
849  plP_line( xpl, ypl );
850 }
851 
852 //--------------------------------------------------------------------------
853 // rdbuf_polyline()
854 //
855 // Draw a polyline in the current color.
856 //--------------------------------------------------------------------------
857 
858 static void
860 {
861  short *xpl, *ypl;
862  PLINT npts;
863 
864  dbug_enter( "rdbuf_polyline" );
865 
866  //read the clipping data first
867  //rd_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
868 // rd_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
869 // rd_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
870 // rd_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
871 
872  //then the number of points
873  rd_data( pls, &npts, sizeof ( PLINT ) );
874 
875  //then the line data
876  // Use the "no copy" version because the node data array does
877  // not need to persist outside of ths function
878  rd_data_no_copy( pls, (void **) &xpl, sizeof ( short ) * (size_t) npts );
879  rd_data_no_copy( pls, (void **) &ypl, sizeof ( short ) * (size_t) npts );
880 
881  plP_polyline( xpl, ypl, npts );
882 }
883 
884 //--------------------------------------------------------------------------
885 // rdbuf_state()
886 //
887 // Handle change in PLStream state (color, pen width, fill attribute, etc).
888 //--------------------------------------------------------------------------
889 
890 static void
892 {
893  U_CHAR op;
894 
895  dbug_enter( "rdbuf_state" );
896 
897  rd_data( pls, &op, sizeof ( U_CHAR ) );
898 
899  switch ( op )
900  {
901  case PLSTATE_WIDTH: {
902  rd_data( pls, &( pls->width ), sizeof ( pls->width ) );
904 
905  break;
906  }
907 
908  case PLSTATE_COLOR0: {
909  U_CHAR r, g, b;
910  PLFLT a;
911 
912  rd_data( pls, &( pls->icol0 ), sizeof ( pls->icol0 ) );
913  if ( pls->icol0 == PL_RGB_COLOR )
914  {
915  rd_data( pls, &r, sizeof ( U_CHAR ) );
916  rd_data( pls, &g, sizeof ( U_CHAR ) );
917  rd_data( pls, &b, sizeof ( U_CHAR ) );
918  rd_data( pls, &a, sizeof ( U_CHAR ) );
919  }
920  else
921  {
922  if ( pls->icol0 >= pls->ncol0 )
923  {
924  char buffer[256];
925  snprintf( buffer, 256,
926  "rdbuf_state: Invalid color map entry: %d",
927  pls->icol0 );
928  plabort( buffer );
929  return;
930  }
931  r = pls->cmap0[pls->icol0].r;
932  g = pls->cmap0[pls->icol0].g;
933  b = pls->cmap0[pls->icol0].b;
934  a = pls->cmap0[pls->icol0].a;
935  }
936  pls->curcolor.r = r;
937  pls->curcolor.g = g;
938  pls->curcolor.b = b;
939  pls->curcolor.a = a;
940  pls->curcmap = 0;
941 
943  break;
944  }
945 
946  case PLSTATE_COLOR1: {
947  rd_data( pls, &( pls->icol1 ), sizeof ( pls->icol1 ) );
948 
949  pls->curcolor.r = pls->cmap1[pls->icol1].r;
950  pls->curcolor.g = pls->cmap1[pls->icol1].g;
951  pls->curcolor.b = pls->cmap1[pls->icol1].b;
952  pls->curcolor.a = pls->cmap1[pls->icol1].a;
953  pls->curcmap = 1;
954 
956  break;
957  }
958 
959  case PLSTATE_FILL: {
960  PLINT patt, nps, inclin[2], delta[2];
961  rd_data( pls, &patt, sizeof ( patt ) );
962  rd_data( pls, &nps, sizeof ( nps ) );
963  rd_data( pls, &inclin[0], sizeof ( inclin ) );
964  rd_data( pls, &delta[0], sizeof ( delta ) );
965  if ( nps != 0 )
966  c_plpat( nps, inclin, delta );
967  pls->patt = patt; //this must be second as c_plpat sets pls->patt to an nvalid value
968  break;
969  }
970 
971  case PLSTATE_CMAP0: {
972  PLINT ncol;
973  size_t size;
974 
975  rd_data( pls, &ncol, sizeof ( ncol ) );
976 
977  // Calculate the memory size for this color palatte
978  size = (size_t) ncol * sizeof ( PLColor );
979 
980  if ( pls->ncol0 == 0 || pls->ncol0 != ncol )
981  {
982  // The current palatte is empty or the current palatte is not
983  // correctly sized, thus we need allocate a new one
984 
985  // If we have a colormap, discard it because we do not use
986  // realloc(). We are going to read the colormap from the buffer
987  if ( pls->cmap0 != NULL )
988  free( pls->cmap0 );
989 
990  if ( ( pls->cmap0 = (PLColor *) malloc( size ) ) == NULL )
991  {
992  plexit( "Insufficient memory for colormap 0" );
993  }
994  }
995 
996  // Now read the colormap from the buffer
997  rd_data( pls, &( pls->cmap0[0] ), size );
998  pls->ncol0 = ncol;
999 
1001  break;
1002  }
1003 
1004  case PLSTATE_CMAP1: {
1005  PLINT ncol;
1006  size_t size;
1007 
1008  rd_data( pls, &ncol, sizeof ( ncol ) );
1009 
1010  // Calculate the memory size for this color palatte
1011  size = (size_t) ncol * sizeof ( PLColor );
1012 
1013  if ( pls->ncol1 == 0 || pls->ncol1 != ncol )
1014  {
1015  // The current palatte is empty or the current palatte is not
1016  // correctly sized, thus we need allocate a new one
1017 
1018  // If we have a colormap, discard it because we do not use
1019  // realloc(). We are going to read the colormap from the buffer
1020  if ( pls->cmap1 != NULL )
1021  free( pls->cmap1 );
1022 
1023  if ( ( pls->cmap1 = (PLColor *) malloc( size ) ) == NULL )
1024  {
1025  plexit( "Insufficient memory for colormap 1" );
1026  }
1027  }
1028 
1029  // Now read the colormap from the buffer
1030  rd_data( pls, &( pls->cmap1[0] ), size );
1031  pls->ncol1 = ncol;
1032 
1034  break;
1035  }
1036 
1037  case PLSTATE_CHR: {
1038  //read the chrdef and chrht parameters
1039  rd_data( pls, &( pls->chrdef ), sizeof ( pls->chrdef ) );
1040  rd_data( pls, &( pls->chrht ), sizeof ( pls->chrht ) );
1041  break;
1042  }
1043 
1044  case PLSTATE_SYM: {
1045  //read the symdef and symht parameters
1046  rd_data( pls, &( pls->symdef ), sizeof ( pls->symdef ) );
1047  rd_data( pls, &( pls->symht ), sizeof ( pls->symht ) );
1048  break;
1049  }
1050 
1051  case PLSTATE_EOFILL: {
1052  rd_data( pls, &( pls->dev_eofill ), sizeof ( pls->dev_eofill ) );
1054  }
1055  }
1056 }
1057 
1058 //--------------------------------------------------------------------------
1059 // rdbuf_esc()
1060 //
1061 // Escape function.
1062 // Must fill data structure with whatever data that was written,
1063 // then call escape function.
1064 //
1065 // Note: it is best to only call the escape function for op-codes that
1066 // are known to be supported.
1067 //
1068 // Functions:
1069 //
1070 // PLESC_FILL Fill polygon
1071 // PLESC_SWIN Set plot window parameters
1072 // PLESC_IMAGE Draw image
1073 // PLESC_HAS_TEXT Draw PostScript text
1074 // PLESC_BEGIN_TEXT Commands for the alternative unicode text
1075 // PLESC_TEXT_CHAR handling path
1076 // PLESC_CONTROL_CHAR
1077 // PLESC_END_TEXT
1078 // PLESC_CLEAR Clear Background
1079 //--------------------------------------------------------------------------
1080 
1081 static void
1083 {
1084  U_CHAR op;
1085 
1086  dbug_enter( "rdbuf_esc" );
1087 
1088  rd_data( pls, &op, sizeof ( U_CHAR ) );
1089 
1090  switch ( op )
1091  {
1092  case PLESC_FILL:
1093  rdbuf_fill( pls );
1094  break;
1095  case PLESC_SWIN:
1096  rdbuf_swin( pls );
1097  break;
1098  case PLESC_IMAGE:
1099  rdbuf_image( pls );
1100  break;
1101  case PLESC_HAS_TEXT:
1102  rdbuf_text( pls );
1103  break;
1104  case PLESC_BEGIN_TEXT:
1105  case PLESC_TEXT_CHAR:
1106  case PLESC_CONTROL_CHAR:
1107  case PLESC_END_TEXT:
1108  // Disable for now because alternative unicode processing is
1109  // not correctly implemented
1110 
1111  //rdbuf_text_unicode( op, pls );
1112  break;
1113  case PLESC_IMPORT_BUFFER:
1114  // Place holder until an appropriate action is determined.
1115  // Should this even be an ESC operation?
1116  break;
1117  case PLESC_CLEAR:
1118  plP_esc( PLESC_CLEAR, NULL );
1119  break;
1120  case PLESC_START_RASTERIZE:
1121  plP_esc( PLESC_START_RASTERIZE, NULL );
1122  break;
1123  case PLESC_END_RASTERIZE:
1124  plP_esc( PLESC_END_RASTERIZE, NULL );
1125  break;
1126  }
1127 }
1128 
1129 //--------------------------------------------------------------------------
1130 // rdbuf_fill()
1131 //
1132 // Fill polygon described by input points.
1133 //--------------------------------------------------------------------------
1134 
1135 static void
1137 {
1138  short *xpl, *ypl;
1139  PLINT npts;
1140 
1141  dbug_enter( "rdbuf_fill" );
1142 
1143  rd_data( pls, &npts, sizeof ( PLINT ) );
1144 
1145  rd_data_no_copy( pls, (void **) &xpl, sizeof ( short ) * (size_t) npts );
1146  rd_data_no_copy( pls, (void **) &ypl, sizeof ( short ) * (size_t) npts );
1147 
1148  plP_fill( xpl, ypl, npts );
1149 }
1150 
1151 //--------------------------------------------------------------------------
1152 //
1153 // rdbuf_clip()
1154 //
1155 //
1156 //--------------------------------------------------------------------------
1157 static void
1159 {
1160  rd_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
1161  rd_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
1162  rd_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
1163  rd_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
1164 }
1165 
1166 //--------------------------------------------------------------------------
1167 // rdbuf_image()
1168 //
1169 // .
1170 //--------------------------------------------------------------------------
1171 
1172 static void
1174 {
1175  // Unnecessarily initialize dev_iy and dev_z to quiet -O1
1176  // -Wuninitialized warnings which are false alarms. (If something
1177  // goes wrong with the dev_ix malloc below any further use of
1178  // dev_iy and dev_z does not occur. Similarly, if something goes
1179  // wrong with the dev_iy malloc below any further use of dev_z
1180  // does not occur.)
1181  short *dev_ix, *dev_iy = NULL;
1182  unsigned short *dev_z = NULL, dev_zmin, dev_zmax;
1183  PLINT nptsX, nptsY, npts;
1184  PLFLT xmin, ymin, dx, dy;
1185 
1186  dbug_enter( "rdbuf_image" );
1187 
1188  rd_data( pls, &nptsX, sizeof ( PLINT ) );
1189  rd_data( pls, &nptsY, sizeof ( PLINT ) );
1190  npts = nptsX * nptsY;
1191 
1192  rd_data( pls, &xmin, sizeof ( PLFLT ) );
1193  rd_data( pls, &ymin, sizeof ( PLFLT ) );
1194  rd_data( pls, &dx, sizeof ( PLFLT ) );
1195  rd_data( pls, &dy, sizeof ( PLFLT ) );
1196 
1197  rd_data( pls, &dev_zmin, sizeof ( short ) );
1198  rd_data( pls, &dev_zmax, sizeof ( short ) );
1199 
1200  // NOTE: Even though for memory buffered version all the data is in memory,
1201  // we still allocate and copy the data because I think that method works
1202  // better in a multithreaded environment. I could be wrong.
1203  //
1204  if ( ( ( dev_ix = (short *) malloc( (size_t) npts * sizeof ( short ) ) ) == NULL ) ||
1205  ( ( dev_iy = (short *) malloc( (size_t) npts * sizeof ( short ) ) ) == NULL ) ||
1206  ( ( dev_z = (unsigned short *) malloc( (size_t) ( ( nptsX - 1 ) * ( nptsY - 1 ) ) * sizeof ( unsigned short ) ) ) == NULL ) )
1207  plexit( "rdbuf_image: Insufficient memory" );
1208 
1209  rd_data( pls, dev_ix, sizeof ( short ) * (size_t) npts );
1210  rd_data( pls, dev_iy, sizeof ( short ) * (size_t) npts );
1211  rd_data( pls, dev_z,
1212  sizeof ( unsigned short )
1213  * (size_t) ( ( nptsX - 1 ) * ( nptsY - 1 ) ) );
1214 
1215  //
1216  // COMMENTED OUT by Hezekiah Carty
1217  // Commented (hopefullly temporarily) until the dev_fastimg rendering
1218  // path can be updated to support the new plimage internals. In the
1219  // meantime this function is not actually used so the issue of how to
1220  // update the code to support the new interface can be ignored.
1221  //
1222  //plP_image(dev_ix, dev_iy, dev_z, nptsX, nptsY, xmin, ymin, dx, dy, dev_zmin, dev_zmax);
1223 
1224  free( dev_ix );
1225  free( dev_iy );
1226  free( dev_z );
1227 }
1228 
1229 //--------------------------------------------------------------------------
1230 // rdbuf_swin()
1231 //
1232 // Set up plot window parameters.
1233 //--------------------------------------------------------------------------
1234 
1235 static void
1237 {
1238  PLWindow plwin;
1239 
1240  dbug_enter( "rdbuf_swin" );
1241 
1242  rd_data( pls, &plwin.dxmi, sizeof ( plwin.dxmi ) );
1243  rd_data( pls, &plwin.dxma, sizeof ( plwin.dxma ) );
1244  rd_data( pls, &plwin.dymi, sizeof ( plwin.dymi ) );
1245  rd_data( pls, &plwin.dyma, sizeof ( plwin.dyma ) );
1246 
1247  rd_data( pls, &plwin.wxmi, sizeof ( plwin.wxmi ) );
1248  rd_data( pls, &plwin.wxma, sizeof ( plwin.wxma ) );
1249  rd_data( pls, &plwin.wymi, sizeof ( plwin.wymi ) );
1250  rd_data( pls, &plwin.wyma, sizeof ( plwin.wyma ) );
1251 
1252  plP_swin( &plwin );
1253 }
1254 
1255 
1256 //--------------------------------------------------------------------------
1257 // rdbuf_swin()
1258 //
1259 // Set up driver interface data
1260 //--------------------------------------------------------------------------
1261 static void
1263 {
1264  PLINT difilt;
1265  PLFLT rot;
1266  PLFLT dimxmin, dimxmax, dimymin, dimymax, dimxpmm, dimypmm;
1267  PLFLT dipxmin, dipymin, dipxmax, dipymax;
1268  PLFLT aspect, mar, jx, jy;
1269  rd_data( pls, &difilt, sizeof ( difilt ) );
1270  rd_data( pls, &dipxmin, sizeof ( dipxmin ) );
1271  rd_data( pls, &dipymin, sizeof ( dipymin ) );
1272  rd_data( pls, &dipxmax, sizeof ( dipxmax ) );
1273  rd_data( pls, &dipymax, sizeof ( dipymax ) );
1274  rd_data( pls, &aspect, sizeof ( aspect ) );
1275  rd_data( pls, &mar, sizeof ( mar ) );
1276  rd_data( pls, &jx, sizeof ( jx ) );
1277  rd_data( pls, &jy, sizeof ( jy ) );
1278  rd_data( pls, &rot, sizeof ( rot ) );
1279  rd_data( pls, &dimxmin, sizeof ( dimxmin ) );
1280  rd_data( pls, &dimymin, sizeof ( dimymin ) );
1281  rd_data( pls, &dimxmax, sizeof ( dimxmax ) );
1282  rd_data( pls, &dimymax, sizeof ( dimymax ) );
1283  rd_data( pls, &dimxpmm, sizeof ( dimxpmm ) );
1284  rd_data( pls, &dimypmm, sizeof ( dimypmm ) );
1285  if ( difilt & PLDI_MAP )
1286  c_plsdimap( dimxmin, dimxmax, dimymin, dimymax, dimxpmm, dimypmm );
1287  if ( difilt & PLDI_ORI )
1288  c_plsdiori( rot );
1289  if ( difilt & PLDI_PLT )
1290  c_plsdiplt( dipxmin, dipymin, dipxmax, dipymax );
1291  if ( difilt & PLDI_DEV )
1292  c_plsdidev( mar, aspect, jx, jy );
1293 }
1294 
1295 //--------------------------------------------------------------------------
1296 // rdbuf_text()
1297 //
1298 // Render text through the driver.
1299 //--------------------------------------------------------------------------
1300 
1301 static void
1303 {
1304  EscText text;
1305  PLFLT xform[4];
1306 
1307  dbug_enter( "rdbuf_text" );
1308 
1309  text.xform = xform;
1310 
1311  // Read the state information
1312 
1313  rd_data( pls, &pls->chrht, sizeof ( pls->chrht ) );
1314  rd_data( pls, &pls->diorot, sizeof ( pls->diorot ) );
1315  //rd_data( pls, &pls->clpxmi, sizeof ( pls->clpxmi ) );
1316 // rd_data( pls, &pls->clpxma, sizeof ( pls->clpxma ) );
1317 // rd_data( pls, &pls->clpymi, sizeof ( pls->clpymi ) );
1318 // rd_data( pls, &pls->clpyma, sizeof ( pls->clpyma ) );
1319 
1320  // Read the text layout information
1321 
1322  rd_data( pls, &text.base, sizeof ( text.base ) );
1323  rd_data( pls, &text.just, sizeof ( text.just ) );
1324  rd_data( pls, text.xform, sizeof ( text.xform[0] ) * 4 );
1325  rd_data( pls, &text.x, sizeof ( text.x ) );
1326  rd_data( pls, &text.y, sizeof ( text.y ) );
1327  rd_data( pls, &text.refx, sizeof ( text.refx ) );
1328  rd_data( pls, &text.refy, sizeof ( text.refy ) );
1329  rd_data( pls, &text.font_face, sizeof ( text.font_face ) );
1330 
1331  // Initialize text arrays to NULL. This protects drivers that
1332  // determine the text representation by looking at which members
1333  // are set.
1334  text.unicode_array_len = 0;
1335  text.unicode_array = NULL;
1336  text.string = NULL;
1337 
1338  // Read in the text
1339  if ( pls->dev_unicode )
1340  {
1341  PLUNICODE fci;
1342 
1343  rd_data( pls, &fci, sizeof ( fci ) );
1344  plsfci( fci );
1345 
1346  rd_data( pls, &text.unicode_array_len, sizeof ( U_SHORT ) );
1347  if ( text.unicode_array_len )
1348  {
1349  // Set the pointer to the unicode data in the buffer. This avoids
1350  // allocating and freeing memory
1352  pls,
1353  (void **) ( &text.unicode_array ),
1354  sizeof ( PLUNICODE ) * text.unicode_array_len );
1355  }
1356  }
1357  else
1358  {
1359  U_SHORT len;
1360 
1361  rd_data( pls, &len, sizeof ( len ) );
1362  if ( len > 0 )
1363  {
1364  // Set the pointer to the string data in the buffer. This avoids
1365  // allocating and freeing memory
1367  pls,
1368  (void **) ( &text.string ),
1369  sizeof ( char ) * len );
1370  }
1371  }
1372 
1373  plP_esc( PLESC_HAS_TEXT, &text );
1374 }
1375 
1376 //--------------------------------------------------------------------------
1377 // rdbuf_text_unicode()
1378 //
1379 // Draw text for the new unicode handling pathway.
1380 // This currently does nothing but is here as a placehlder for the future
1381 //--------------------------------------------------------------------------
1382 
1383 static void
1385 {
1386  dbug_enter( "rdbuf_text_unicode" );
1387 }
1388 
1389 //--------------------------------------------------------------------------
1390 // plRemakePlot()
1391 //
1392 // Rebuilds plot from plot buffer, usually in response to a window
1393 // resize or exposure event.
1394 //--------------------------------------------------------------------------
1395 
1396 void
1398 {
1399  //set the current status to end of page, so that the begin page code
1400  //gets called
1401  plsc->page_status = AT_EOP;
1402  plFlushBuffer( pls, TRUE, (size_t) ( -1 ) );
1403 }
1404 
1405 //--------------------------------------------------------------------------
1406 // plFlushBuffer( )
1407 //
1408 // Flush the current contents of the buffer to the plot either restarting
1409 // from the beginning of the buffer or continuing from the current read
1410 // location. Setting amount to -1 will flush to the end, setting it to
1411 // another value flushes until at least that amount has been flushed then
1412 // stops
1413 //--------------------------------------------------------------------------
1414 
1415 void
1416 plFlushBuffer( PLStream *pls, PLBOOL restart, size_t amount )
1417 {
1418  U_CHAR c;
1420  PLINT cursub;
1421 
1422  dbug_enter( "plRemakePlot" );
1423 
1424  // Change the status of the flags before checking for a buffer.
1425  // Actually, more thought is needed if we want to support multithreaded
1426  // code correctly, specifically the case where two threads are using
1427  // the same plot stream (e.g. one thread is drawing the plot and another
1428  // thread is processing window manager messages).
1429  //
1430  plbuf_write = pls->plbuf_write;
1431  cursub = pls->cursub;
1432  pls->plbuf_write = FALSE;
1433  pls->plbuf_read = TRUE;
1434 
1435  if ( pls->plbuf_buffer )
1436  {
1437  // State saving variables
1438  PLStream *save_current_pls;
1439  size_t finalReadPos;
1440 
1441  // Save state
1442 
1443  // Need to change where plsc (current plot stream) points to before
1444  // processing the commands. If we have multiple plot streams, this
1445  // will prevent the commands from going to the wrong plot stream.
1446  //
1447  save_current_pls = plsc;
1448 
1449  // Make the current plot stream the one passed by the caller
1450  plsc = pls;
1451 
1452  if ( restart )
1453  {
1454  pls->plbuf_readpos = 0;
1455 
1456  //end any current page on the destination stream.
1457  //This will do nothing if we are already at the end
1458  //of a page.
1459  //Doing this ensures that the first bop command in the
1460  //buffer actually does something
1461  //plP_eop();
1462  }
1463 
1464  finalReadPos = amount == (size_t) ( -1 ) ? pls->plbuf_top : MIN( pls->plbuf_readpos + amount, pls->plbuf_top );
1465 
1466  // Replay the plot command buffer
1467  while ( rd_command( pls, &c ) && pls->plbuf_readpos < finalReadPos )
1468  {
1469  plbuf_control( pls, c );
1470  }
1471 
1472  // Restore the original current plot stream
1473  plsc = save_current_pls;
1474  }
1475 
1476  // Restore the state of the passed plot stream
1477  pls->plbuf_read = FALSE;
1478  pls->plbuf_write = plbuf_write;
1479  pls->cursub = cursub;
1480 }
1481 
1482 //--------------------------------------------------------------------------
1483 // plbuf_control()
1484 //
1485 // Processes commands read from the plot buffer.
1486 //--------------------------------------------------------------------------
1487 
1488 static void
1490 {
1491  static U_CHAR c_old = 0;
1492  static U_CHAR esc_old = 0;
1493 
1494  dbug_enter( "plbuf_control" );
1495 
1496  //#define CLOSE 2
1497  //#define LINETO 10
1498  //#define END_OF_FIELD 255
1499 
1500  switch ( (int) c )
1501  {
1502  case INITIALIZE:
1503  rdbuf_init( pls );
1504  break;
1505 
1506  case EOP:
1507  rdbuf_eop( pls );
1508  break;
1509 
1510  case BOP0:
1511  case BOP:
1512  rdbuf_bop( pls );
1513  break;
1514 
1515  case CHANGE_STATE:
1516  rdbuf_state( pls );
1517  break;
1518 
1519  case LINE:
1520  rdbuf_line( pls );
1521  break;
1522 
1523  case POLYLINE:
1524  rdbuf_polyline( pls );
1525  break;
1526 
1527  case ESCAPE:
1528  esc_old = *( (U_CHAR *) ( pls->plbuf_buffer ) + pls->plbuf_readpos );
1529  rdbuf_esc( pls );
1530  break;
1531 
1532  case DRIVER_INTERFACE:
1533  rdbuf_di( pls );
1534  break;
1535 
1536  case SETSUB:
1537  rdbuf_setsub( pls );
1538  break;
1539 
1540  case SSUB:
1541  rdbuf_ssub( pls );
1542  break;
1543 
1544  case CLIP:
1545  rdbuf_clip( pls );
1546  break;
1547 
1548  // Obsolete commands, left here to maintain compatibility with previous
1549  // version of plot metafiles
1550  case SWITCH_TO_TEXT: // Obsolete, replaced by ESCAPE
1551  case SWITCH_TO_GRAPH: // Obsolete, replaced by ESCAPE
1552  case NEW_COLOR: // Obsolete, replaced by CHANGE_STATE
1553  case NEW_COLOR1:
1554  case NEW_WIDTH: // Obsolete, replaced by CHANGE_STATE
1555  case ADVANCE: // Obsolete, BOP/EOP used instead
1556  pldebug( "plbuf_control", "Obsolete command %d, ignoring\n", c );
1557  break;
1558 
1559  default:
1560  pldebug( "plbuf_control", "Unrecognized command %d, previous %d\n",
1561  c, c_old );
1562  plexit( "Unrecognized command" );
1563  }
1564  c_old = c;
1565 }
1566 
1567 //--------------------------------------------------------------------------
1568 // rd_command()
1569 //
1570 // Read & return the next command
1571 //--------------------------------------------------------------------------
1572 
1573 static int
1575 {
1576  int count;
1577 
1578  if ( pls->plbuf_readpos < pls->plbuf_top )
1579  {
1580  *p_c = *(U_CHAR *) ( (uint8_t *) pls->plbuf_buffer + pls->plbuf_readpos );
1581 
1582  // Advance the buffer position to maintain two-byte alignment
1583  pls->plbuf_readpos += sizeof ( uint16_t );
1584 
1585  count = sizeof ( U_CHAR );
1586  }
1587  else
1588  {
1589  count = 0;
1590  }
1591 
1592  return ( count );
1593 }
1594 
1595 //--------------------------------------------------------------------------
1596 // rd_data()
1597 //
1598 // Read the data associated with the command
1599 //--------------------------------------------------------------------------
1600 
1601 static void
1602 rd_data( PLStream *pls, void *buf, size_t buf_size )
1603 {
1604  memcpy( buf, (uint8_t *) pls->plbuf_buffer + pls->plbuf_readpos, buf_size );
1605 
1606  // Advance position but maintain alignment
1607  pls->plbuf_readpos += ( buf_size + ( buf_size % sizeof ( uint16_t ) ) );
1608 }
1609 
1610 //--------------------------------------------------------------------------
1611 // rd_data_no_copy()
1612 //
1613 // Read the data associated with the command by setting a pointer to the
1614 // position in the plot buffer. This avoids having to allocate space
1615 // and doing a memcpy. Useful for commands that do not need the data
1616 // to persist (like LINE and POLYLINE). Do not use for commands that
1617 // has data that needs to persist or are freed elsewhere (like COLORMAPS).
1618 //--------------------------------------------------------------------------
1619 
1620 static void
1621 rd_data_no_copy( PLStream *pls, void **buf, size_t buf_size )
1622 {
1623  ( *buf ) = (uint8_t *) pls->plbuf_buffer + pls->plbuf_readpos;
1624 
1625  // Advance position but maintain alignment
1626  pls->plbuf_readpos += ( buf_size + ( buf_size % sizeof ( uint16_t ) ) );
1627 }
1628 
1629 //--------------------------------------------------------------------------
1630 // check_buffer_size()
1631 //
1632 // Checks that the buffer has space to store the desired amount of data.
1633 // If not, the buffer is resized to accomodate the request
1634 //--------------------------------------------------------------------------
1635 static void
1636 check_buffer_size( PLStream *pls, size_t data_size )
1637 {
1638  size_t required_size;
1639 
1640  required_size = pls->plbuf_top + data_size;
1641 
1642  if ( required_size >= pls->plbuf_buffer_size )
1643  {
1644  if ( pls->plbuf_buffer_grow == 0 )
1645  pls->plbuf_buffer_grow = 128 * 1024;
1646 
1647  // Not enough space, need to grow the buffer before memcpy
1648  // Must make sure the increase is enough for this data, so
1649  // Determine the amount of space required and grow in multiples
1650  // of plbuf_buffer_grow
1651  pls->plbuf_buffer_size += pls->plbuf_buffer_grow *
1652  ( ( required_size
1653  - pls->plbuf_buffer_size )
1654  / pls->plbuf_buffer_grow
1655  + 1 );
1656 
1657  if ( pls->verbose )
1658  printf( "Growing buffer to %d KB\n",
1659  (int) ( pls->plbuf_buffer_size / 1024 ) );
1660 
1661  if ( ( pls->plbuf_buffer
1662  = realloc( pls->plbuf_buffer, pls->plbuf_buffer_size )
1663  ) == NULL )
1664  plexit( "plbuf buffer grow: Plot buffer grow failed" );
1665  }
1666 }
1667 
1668 //--------------------------------------------------------------------------
1669 // wr_command()
1670 //
1671 // Write the next command
1672 //--------------------------------------------------------------------------
1673 
1674 static void
1676 {
1677  check_buffer_size( pls, sizeof ( uint16_t ) );
1678 
1679  *(U_CHAR *) ( (uint8_t *) pls->plbuf_buffer + pls->plbuf_top ) = c;
1680 
1681  // Advance buffer position to maintain two-byte alignment. This
1682  // will waste a little bit of space, but it prevents memory
1683  // alignment problems
1684  pls->plbuf_top += sizeof ( uint16_t );
1685 }
1686 
1687 //--------------------------------------------------------------------------
1688 // wr_data()
1689 //
1690 // Write the data associated with a command
1691 //--------------------------------------------------------------------------
1692 
1693 static void
1694 wr_data( PLStream *pls, void *buf, size_t buf_size )
1695 {
1696  check_buffer_size( pls, buf_size + ( buf_size % sizeof ( uint16_t ) ) );
1697  memcpy( (uint8_t *) pls->plbuf_buffer + pls->plbuf_top, buf, buf_size );
1698 
1699  // Advance position but maintain alignment
1700  pls->plbuf_top += ( buf_size + ( buf_size % sizeof ( uint16_t ) ) );
1701 }
1702 
1703 
1704 //--------------------------------------------------------------------------
1705 // Plot buffer state saving
1706 //--------------------------------------------------------------------------
1707 
1708 // plbuf_save(state)
1709 //
1710 // Saves the current state of the plot into a save buffer. The
1711 // original code used a temporary file for the plot buffer and memory
1712 // to perserve colormaps. That method does not offer a clean break
1713 // between using memory buffers and file buffers. This function
1714 // preserves the same functionality by returning a data structure that
1715 // saves the plot buffer.
1716 //
1717 // The caller passes an existing save buffer for reuse or NULL
1718 // to force the allocation of a new buffer. Since one malloc()
1719 // is used for everything, the entire save buffer can be freed
1720 // with one free() call.
1721 //
1722 //
1723 struct _state
1724 {
1725  size_t size; // Size of the save buffer
1726  int valid; // Flag to indicate a valid save state
1729  size_t plbuf_top;
1731 };
1732 
1733 void * plbuf_save( PLStream *pls, void *state )
1734 {
1735  size_t save_size;
1736  struct _state *plot_state = (struct _state *) state;
1737  PLINT i;
1738  U_CHAR *buf; // Assume that this is byte-sized
1739 
1740  dbug_enter( "plbuf_save" );
1741 
1742  // If the plot buffer is not being used, there is no state to save
1743  if ( !pls->plbuf_write )
1744  return NULL;
1745 
1746  pls->plbuf_write = FALSE;
1747  pls->plbuf_read = TRUE;
1748 
1749  // Determine the size of the buffer required to save everything.
1750  save_size = sizeof ( struct _state );
1751 
1752  // Only copy as much of the plot buffer that is being used
1753  save_size += pls->plbuf_top;
1754 
1755  // If a buffer exists, determine if we need to resize it
1756  if ( state != NULL )
1757  {
1758  // We have a save buffer, is it smaller than the current size
1759  // requirement?
1760  if ( plot_state->size < save_size )
1761  {
1762  // Yes, reallocate a larger one
1763  if ( ( plot_state = (struct _state *) realloc( state, save_size ) ) == NULL )
1764  {
1765  // NOTE: If realloc fails, then plot_state will be NULL.
1766  // This will leave the original buffer untouched, thus we
1767  // mark it as invalid and return it back to the caller.
1768  //
1769  plwarn( "plbuf: Unable to reallocate sufficient memory to save state" );
1770  plot_state->valid = 0;
1771 
1772  return state;
1773  }
1774  plot_state->size = save_size;
1775  }
1776  }
1777  else
1778  {
1779  // A buffer does not exist, so we need to allocate one
1780  if ( ( plot_state = (struct _state *) malloc( save_size ) ) == NULL )
1781  {
1782  plwarn( "plbuf: Unable to allocate sufficient memory to save state" );
1783 
1784  return NULL;
1785  }
1786  plot_state->size = save_size;
1787  }
1788 
1789  // At this point we have an appropriately sized save buffer.
1790  // We need to invalidate the state of the save buffer, since it
1791  // will not be valid until after everything is copied. We use
1792  // this approach vice freeing the memory and returning a NULL pointer
1793  // in order to prevent allocating and freeing memory needlessly.
1794  //
1795  plot_state->valid = 0;
1796 
1797  // Point buf to the space after the struct _state
1798  buf = (U_CHAR *) ( plot_state + 1 );
1799 
1800  // Again, note, that we only copy the portion of the plot buffer that
1801  // is being used
1802  plot_state->plbuf_buffer_size = pls->plbuf_top;
1803  plot_state->plbuf_top = pls->plbuf_top;
1804  plot_state->plbuf_readpos = 0;
1805 
1806  // Create a pointer that points in the space we allocated after
1807  // struct _state
1808  plot_state->plbuf_buffer = (void *) buf;
1809  buf += pls->plbuf_top;
1810 
1811  // Copy the plot buffer to our new buffer. Again, I must stress, that
1812  // we only are copying the portion of the plot buffer that is being used
1813  //
1814  if ( memcpy( plot_state->plbuf_buffer, pls->plbuf_buffer, pls->plbuf_top ) == NULL )
1815  {
1816  // This should never be NULL
1817  plwarn( "plbuf: Got a NULL in memcpy!" );
1818  return (void *) plot_state;
1819  }
1820 
1821  pls->plbuf_write = TRUE;
1822  pls->plbuf_read = FALSE;
1823 
1824  plot_state->valid = 1;
1825  return (void *) plot_state;
1826 }
1827 
1828 // plbuf_restore(PLStream *, state)
1829 //
1830 // Restores the passed state
1831 //
1832 void plbuf_restore( PLStream *pls, void *state )
1833 {
1834  struct _state *new_state = (struct _state *) state;
1835 
1836  dbug_enter( "plbuf_restore" );
1837 
1838  pls->plbuf_buffer = new_state->plbuf_buffer;
1839  pls->plbuf_buffer_size = new_state->plbuf_buffer_size;
1840  pls->plbuf_top = new_state->plbuf_top;
1841  pls->plbuf_readpos = new_state->plbuf_readpos;
1842 }
1843 
1844 // plbuf_switch(PLStream *, state)
1845 //
1846 // Makes the passed state the current one. Preserves the previous state
1847 // by returning a save buffer.
1848 //
1849 // NOTE: The current implementation can cause a memory leak under the
1850 // following scenario:
1851 // 1) plbuf_save() is called
1852 // 2) plbuf_switch() is called
1853 // 3) Commands are called which cause the plot buffer to grow
1854 // 4) plbuf_swtich() is called
1855 //
1856 void * plbuf_switch( PLStream *pls, void *state )
1857 {
1858  struct _state *new_state = (struct _state *) state;
1859  struct _state *prev_state;
1860  size_t save_size;
1861 
1862  dbug_enter( "plbuf_switch" );
1863 
1864  // No saved state was passed, return a NULL--we hope the caller
1865  // is smart enough to notice
1866  //
1867  if ( state == NULL )
1868  return NULL;
1869 
1870  if ( !new_state->valid )
1871  {
1872  plwarn( "plbuf: Attempting to switch to an invalid saved state" );
1873  return NULL;
1874  }
1875 
1876  save_size = sizeof ( struct _state );
1877 
1878  if ( ( prev_state = (struct _state *) malloc( save_size ) ) == NULL )
1879  {
1880  plwarn( "plbuf: Unable to allocate memory to save state" );
1881  return NULL;
1882  }
1883 
1884  // Set some housekeeping variables
1885  prev_state->size = save_size;
1886  prev_state->valid = 1;
1887 
1888  // Preserve the existing state
1889  prev_state->plbuf_buffer = pls->plbuf_buffer;
1890  prev_state->plbuf_buffer_size = pls->plbuf_buffer_size;
1891  prev_state->plbuf_top = pls->plbuf_top;
1892  prev_state->plbuf_readpos = pls->plbuf_readpos;
1893 
1894  plbuf_restore( pls, new_state );
1895 
1896  return (void *) prev_state;
1897 }
unsigned short * dev_z
Definition: plstrm.h:588
#define PLSTATE_CMAP0
Definition: plplotP.h:366
PLINT inclin[2]
Definition: plstrm.h:669
PLFLT dymi
Definition: plplot.h:452
void c_plsdidev(PLFLT mar, PLFLT aspect, PLFLT jx, PLFLT jy)
Definition: plcore.c:1892
static void wr_command(PLStream *pls, U_CHAR c)
Definition: plbuf.c:1675
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1958
Definition: plbuf.c:1723
void plP_esc(PLINT op, void *ptr)
Definition: plcore.c:273
static void wr_data(PLStream *pls, void *buf, size_t buf_size)
Definition: plbuf.c:1694
PLINT icol1
Definition: plstrm.h:539
#define PLESC_CONTROL_CHAR
Definition: plplot.h:300
void c_plsdiori(PLFLT rot)
Definition: plcore.c:2022
PLFLT just
Definition: plplotP.h:708
void plbuf_state(PLStream *pls, PLINT op)
Definition: plbuf.c:295
#define BOP0
Definition: metadefs.h:69
static void rdbuf_text_unicode(PLINT op, PLStream *pls)
Definition: plbuf.c:1384
void c_plssub(PLINT nx, PLINT ny)
Definition: plcore.c:3617
PLFLT dimymin
Definition: plstrm.h:664
unsigned char b
Definition: plplot.h:550
#define PLSTATE_SYM
Definition: plplotP.h:369
static void plbuf_image(PLStream *pls, IMG_DT *img_dt)
Definition: plbuf.c:373
size_t plbuf_top
Definition: plstrm.h:650
unsigned short dev_zmin
Definition: plstrm.h:589
PLFLT dxma
Definition: plplot.h:452
#define PLESC_FILL
Definition: plplot.h:279
#define PL_RGB_COLOR
Definition: plplotP.h:285
static void rdbuf_line(PLStream *pls)
Definition: plbuf.c:830
#define DRIVER_INTERFACE
Definition: metadefs.h:70
void c_plpat(PLINT nlin, PLINT_VECTOR inc, PLINT_VECTOR del)
Definition: plsdef.c:293
#define INITIALIZE
Definition: metadefs.h:53
void plbuf_di(PLStream *pls)
Definition: plbuf.c:571
PLFLT mar
Definition: plstrm.h:659
void plbuf_clip(PLStream *pls)
Definition: plbuf.c:615
#define ADVANCE
Definition: metadefs.h:64
PLFLT dxmi
Definition: plplot.h:452
PLUINT PLUNICODE
Definition: plplot.h:201
short * dev_iy
Definition: plstrm.h:587
#define CLIP
Definition: metadefs.h:73
void plbuf_restore(PLStream *pls, void *state)
Definition: plbuf.c:1832
#define SETSUB
Definition: metadefs.h:71
PLFLT jy
Definition: plstrm.h:659
PLINT dev_npts
Definition: plstrm.h:581
PLINT curcmap
Definition: plstrm.h:539
void plP_swin(PLWindow *plwin)
Definition: plcore.c:308
size_t plbuf_buffer_size
Definition: plbuf.c:1728
PLINT dev_unicode
Definition: plstrm.h:747
#define PLESC_END_TEXT
Definition: plplot.h:301
PLINT plbuf_write
Definition: plstrm.h:567
PLFLT diorot
Definition: plstrm.h:661
PLFLT a
Definition: plplot.h:551
PLFLT jx
Definition: plstrm.h:659
void * plbuf_switch(PLStream *pls, void *state)
Definition: plbuf.c:1856
void plFlushBuffer(PLStream *pls, PLBOOL restart, size_t amount)
Definition: plbuf.c:1416
PLFLT dipymin
Definition: plstrm.h:657
PLINT dev_nptsY
Definition: plstrm.h:586
#define PLSTATE_COLOR0
Definition: plplotP.h:363
static void plbuf_fill(PLStream *pls)
Definition: plbuf.c:600
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1894
#define PLSTATE_COLOR1
Definition: plplotP.h:364
#define U_SHORT
Definition: pdf.h:30
int valid
Definition: plbuf.c:1726
void plbuf_init(PLStream *pls)
Definition: plbuf.c:89
static void rdbuf_ssub(PLStream *pls)
Definition: plbuf.c:816
PLColor * cmap1
Definition: plstrm.h:545
void plbuf_esc(PLStream *pls, PLINT op, void *ptr)
Definition: plbuf.c:494
PLFLT dimxmax
Definition: plstrm.h:664
#define PLDI_DEV
Definition: plplotP.h:381
short * dev_x
Definition: plstrm.h:582
size_t size
Definition: plbuf.c:1725
static void check_buffer_size(PLStream *pls, size_t data_size)
Definition: plbuf.c:1636
#define PLESC_TEXT_CHAR
Definition: plplot.h:299
#define PLSTATE_WIDTH
Definition: plplotP.h:362
static void rdbuf_swin(PLStream *pls)
Definition: plbuf.c:1236
int PLINT
Definition: plplot.h:181
PLFLT ymin
Definition: plplotP.h:1205
#define MIN(a, b)
Definition: dsplint.c:29
PLINT PLBOOL
Definition: plplot.h:204
PLFLT aspect
Definition: plstrm.h:659
void plP_polyline(short *x, short *y, PLINT npts)
Definition: plcore.c:417
void plP_bop(void)
Definition: plcore.c:198
static void rdbuf_text(PLStream *pls)
Definition: plbuf.c:1302
unsigned short dev_zmax
Definition: plstrm.h:589
#define PLSTATE_FILL
Definition: plplotP.h:365
#define NEW_WIDTH
Definition: metadefs.h:60
PLFLT dimymax
Definition: plstrm.h:664
PLINT dev_nptsX
Definition: plstrm.h:586
PLINT refy
Definition: plplotP.h:717
PLINT ncol0
Definition: plstrm.h:539
unsigned char g
Definition: plplot.h:549
static void plbuf_text_unicode(PLStream *pls, EscText *text)
Definition: plbuf.c:468
int nplwin
Definition: plstrm.h:718
PLFLT wymi
Definition: plplot.h:453
PLINT clpymi
Definition: plstrm.h:704
void plbuf_polyline(PLStream *pls, short *xa, short *ya, PLINT npts)
Definition: plbuf.c:268
#define snprintf
Definition: plplotP.h:235
#define PLSTATE_CMAP1
Definition: plplotP.h:367
PLINT icol0
Definition: plstrm.h:539
static void rdbuf_esc(PLStream *pls)
Definition: plbuf.c:1082
static void rdbuf_eop(PLStream *pls)
PLINT nsuby
Definition: plstrm.h:723
#define dbug_enter(a)
Definition: tclMatrix.c:59
#define PLDI_PLT
Definition: plplotP.h:380
#define TRUE
Definition: plplotP.h:176
static void rdbuf_fill(PLStream *pls)
Definition: plbuf.c:1136
PLFLT dipymax
Definition: plstrm.h:657
#define ESCAPE
Definition: metadefs.h:63
#define PLDI_ORI
Definition: plplotP.h:379
#define PLESC_FLUSH_REMAINING_BUFFER
Definition: plplot.h:311
void plbuf_tidy(PLStream *PL_UNUSED(pls))
Definition: plbuf.c:225
#define FALSE
Definition: plplotP.h:177
PLINT nsubx
Definition: plstrm.h:723
#define EOP
Definition: metadefs.h:57
static void rdbuf_bop(PLStream *pls)
Definition: plbuf.c:696
void difilt(PLINT *xsc, PLINT *ysc, PLINT npts, PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma)
Definition: plcore.c:1460
#define PLESC_END_RASTERIZE
Definition: plplot.h:303
#define PLESC_CLEAR
Definition: plplot.h:288
PLFLT symdef
Definition: plstrm.h:687
PLINT verbose
Definition: plstrm.h:527
static PLINT * buffer
Definition: plfill.c:74
static void rdbuf_polyline(PLStream *pls)
Definition: plbuf.c:859
size_t size
Definition: plplot.h:629
void xform(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data)
PLColor * cmap0
Definition: plstrm.h:544
size_t plbuf_buffer_grow
Definition: plstrm.h:647
void plbuf_ssub(PLStream *pls)
Definition: plbuf.c:209
#define PLSTATE_EOFILL
Definition: plplotP.h:370
static void rdbuf_setsub(PLStream *pls)
Definition: plbuf.c:803
PLFLT dyma
Definition: plplot.h:452
PLFLT dimxpmm
Definition: plstrm.h:664
#define PLESC_APPEND_BUFFER
Definition: plplot.h:310
PLFLT wyma
Definition: plplot.h:453
static char buf[200]
Definition: tclAPI.c:873
PLINT clpxmi
Definition: plstrm.h:704
static PLStream * pls[PL_NSTREAMS]
Definition: plcore.h:88
PLFLT wxmi
Definition: plplot.h:453
#define plgfci
Definition: plplot.h:735
PLFLT dx
Definition: plplotP.h:1205
#define PLESC_BEGIN_TEXT
Definition: plplot.h:298
#define LINE
Definition: metadefs.h:61
static void rdbuf_init(PLStream *pls)
void plP_setsub(void)
Definition: plpage.c:189
void plbuf_line(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
Definition: plbuf.c:237
#define SSUB
Definition: metadefs.h:72
unsigned short unicode_array_len
Definition: plplotP.h:736
static void plbuf_text(PLStream *pls, EscText *text)
Definition: plbuf.c:404
short * dev_y
Definition: plstrm.h:582
void * plbuf_buffer
Definition: plbuf.c:1727
static void plbuf_swin(PLStream *pls, PLWindow *plwin)
Definition: plbuf.c:634
static int text
Definition: ps.c:77
void plbuf_setsub(PLStream *pls)
Definition: plbuf.c:192
static void rdbuf_image(PLStream *pls)
Definition: plbuf.c:1173
PLFLT dimxmin
Definition: plstrm.h:664
void plP_state(PLINT op)
Definition: plcore.c:256
PLINT refx
Definition: plplotP.h:716
void plP_fill(short *x, short *y, PLINT npts)
Definition: plcore.c:451
#define PLESC_SWIN
Definition: plplot.h:284
void * plbuf_save(PLStream *pls, void *state)
Definition: plbuf.c:1733
static void rd_data_no_copy(PLStream *pls, void **buf, size_t buf_size)
Definition: plbuf.c:1621
short * dev_ix
Definition: plstrm.h:587
#define PL_UNUSED(x)
Definition: plplot.h:138
void plRemakePlot(PLStream *pls)
Definition: plbuf.c:1397
float PLFLT
Definition: plplot.h:163
PLFLT dipxmax
Definition: plstrm.h:657
#define PLESC_START_RASTERIZE
Definition: plplot.h:302
PLFLT chrht
Definition: plstrm.h:686
static void rdbuf_di(PLStream *pls)
Definition: plbuf.c:1262
PLINT plbuf_read
Definition: plstrm.h:567
void c_plsdimap(PLINT dimxmin, PLINT dimxmax, PLINT dimymin, PLINT dimymax, PLFLT dimxpmm, PLFLT dimypmm)
Definition: plcore.c:2160
size_t plbuf_top
Definition: plbuf.c:1729
#define SWITCH_TO_TEXT
Definition: metadefs.h:55
PLFLT dimypmm
Definition: plstrm.h:664
#define PLESC_IMPORT_BUFFER
Definition: plplot.h:309
void plP_line(short *x, short *y)
Definition: plcore.c:388
void plbuf_eop(PLStream *pls)
Definition: plbuf.c:122
PLINT patt
Definition: plstrm.h:669
PLINT difilt
Definition: plstrm.h:656
static void plbuf_control(PLStream *pls, U_CHAR c)
Definition: plbuf.c:1489
#define PLSTATE_CHR
Definition: plplotP.h:368
unsigned char r
Definition: plplot.h:548
#define PLESC_HAS_TEXT
Definition: plplot.h:290
PLFLT width
Definition: plstrm.h:552
void * plbuf_buffer
Definition: plstrm.h:649
void plwarn(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1863
PLFLT wxma
Definition: plplot.h:453
PLINT y
Definition: plplotP.h:713
void plbuf_bop(PLStream *pls)
Definition: plbuf.c:141
PLINT cursub
Definition: plstrm.h:723
#define PLDI_MAP
Definition: plplotP.h:378
#define CHANGE_STATE
Definition: metadefs.h:68
#define PLESC_IMAGE
Definition: plplot.h:291
PLColor curcolor
Definition: plstrm.h:543
#define SWITCH_TO_GRAPH
Definition: metadefs.h:56
PLINT nps
Definition: plstrm.h:669
static int rd_command(PLStream *pls, U_CHAR *p_c)
Definition: plbuf.c:1574
PLINT clpxma
Definition: plstrm.h:704
const char * string
Definition: plplotP.h:739
#define POLYLINE
Definition: metadefs.h:65
void plbuf_write(PLStream *pls, void *data, size_t bytes)
Definition: plbuf.c:660
#define NEW_COLOR1
Definition: metadefs.h:67
PLPointer buffer
Definition: plplot.h:630
size_t plbuf_readpos
Definition: plstrm.h:651
PLFLT dipxmin
Definition: plstrm.h:657
PLINT ncol1
Definition: plstrm.h:539
size_t plbuf_readpos
Definition: plbuf.c:1730
PLINT x
Definition: plplotP.h:712
PLFLT chrdef
Definition: plstrm.h:686
PLFLT symht
Definition: plstrm.h:687
#define plsfci
Definition: plplot.h:817
static void rdbuf_clip(PLStream *pls)
Definition: plbuf.c:1158
PLUNICODE * unicode_array
Definition: plplotP.h:735
char font_face
Definition: plplotP.h:720
PLINT delta[2]
Definition: plstrm.h:669
static void rdbuf_state(PLStream *pls)
Definition: plbuf.c:891
size_t plbuf_buffer_size
Definition: plstrm.h:648
#define BOP
Definition: metadefs.h:58
static void rd_data(PLStream *pls, void *buf, size_t buf_size)
Definition: plbuf.c:1602
PLFLT * xform
Definition: plplotP.h:709
#define U_CHAR
Definition: pdf.h:26
void c_plsdiplt(PLFLT xmin, PLFLT ymin, PLFLT xmax, PLFLT ymax)
Definition: plcore.c:1782
PLINT dev_eofill
Definition: plstrm.h:788
PLFLT dy
Definition: plplotP.h:1205
PLINT base
Definition: plplotP.h:707
PLFLT xmin
Definition: plplotP.h:1205
#define NEW_COLOR
Definition: metadefs.h:59
PLINT clpyma
Definition: plstrm.h:704