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