File: g_closepl.c

package info (click to toggle)
plotutils 2.4.1-15
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 11,072 kB
  • ctags: 6,952
  • sloc: ansic: 76,305; cpp: 12,402; sh: 8,475; yacc: 2,604; makefile: 894; lex: 144
file content (175 lines) | stat: -rw-r--r-- 5,472 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* This file contains the closepl method, which is a standard part of
   libplot.  It closes a Plotter object. */

/* This generic version does only basic mechanics, since GenericPlotters
   don't emit any graphics code. */

#include "sys-defines.h"
#include "extern.h"

int
#ifdef _HAVE_PROTOS
_API_closepl (S___(Plotter *_plotter))
#else
_API_closepl (S___(_plotter))
     S___(Plotter *_plotter;)
#endif
{
  bool emit_not_just_the_first_page = true;
  bool retval1;
  int retval2 = 0;

  if (!_plotter->data->open)
    {
      _plotter->error (R___(_plotter) 
		       "closepl: invalid operation");
      return -1;
    }

  _API_endpath (S___(_plotter)); /* flush path if any */

  /* pop drawing states in progress, if any, off the stack */
  if (_plotter->drawstate->previous != NULL)
    {
      while (_plotter->drawstate->previous)
	_API_restorestate (S___(_plotter));
    }
  
  /* invoke Plotter-specific method to end the page; also do
     device-dependent teardown Plotter-specific drawing state variables, do
     reinitialization of Plotter-specific Plotter variables, and create
     page header and trailer if any */
  retval1 = _plotter->end_page (S___(_plotter));

  /* remove first drawing state too, so we can start afresh */
  _delete_first_drawing_state (S___(_plotter));

  switch ((int)_plotter->data->output_model)
    {
    case (int)PL_OUTPUT_NONE:
      /* we don't do output, so just delete the page buffer (presumably it
	 includes neither a header nor a trailer) */
      if (_plotter->data->page)
	_delete_outbuf (_plotter->data->page);
      _plotter->data->page = (plOutbuf *)NULL;
      break;

    case (int)PL_OUTPUT_ONE_PAGE:
      emit_not_just_the_first_page = false;
      /* fall through */

    case (int)PL_OUTPUT_ONE_PAGE_AT_A_TIME:
      if (_plotter->data->page
	  && (emit_not_just_the_first_page 
	      || _plotter->data->page_number == 1))
	{
	  /* emit page header if any */
	  if (_plotter->data->page->header 
	      && _plotter->data->page->header->len > 0)
	    _write_string (_plotter->data, 
			   _plotter->data->page->header->base); 

	  /* emit all the graphics on the page */
	  if (_plotter->data->page && _plotter->data->page->len > 0)
	    _write_string (_plotter->data, _plotter->data->page->base); 

	  /* emit page trailer if any */
	  if (_plotter->data->page->trailer 
	      && _plotter->data->page->trailer->len > 0)
	    _write_string (_plotter->data, 
			   _plotter->data->page->trailer->base); 

	  /* attempt to flush (will test whether stream is jammed) */
	  retval2 = _API_flushpl (S___(_plotter));
	}
      
      /* delete page header if any */
      if (_plotter->data->page->header)
	_delete_outbuf (_plotter->data->page->header);
      _plotter->data->page->header = (plOutbuf *)NULL;

      /* delete page trailer if any */
      if (_plotter->data->page->trailer)
	_delete_outbuf (_plotter->data->page->trailer);
      _plotter->data->page->trailer = (plOutbuf *)NULL;

      /* delete page's plOutbuf */
      if (_plotter->data->page)
	_delete_outbuf (_plotter->data->page);
      _plotter->data->page = (plOutbuf *)NULL;

      break;
      
    case (int)PL_OUTPUT_PAGES_ALL_AT_ONCE:
      /* Plotter will do its own output, in its terminate() routine.  
	 It will do so by writing out the contents of all its cached pages
	 (a new one gets added to the list each time openpl() is invoked).
	 So do nothing. */
      break;

    case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES:
    case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES_IN_REAL_TIME:
      /* Plotter does its own output, and doesn't use libplot's
	 plOutbuf-based output system.  So do nothing, except
	 attempt to flush (will test whether stream is jammed) */
      retval2 = _API_flushpl (S___(_plotter));
      break;

    case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES_TO_NON_STREAM:
      /* Plotter doesn't use libplot's plOutbuf-based output system, and in
	 fact doesn't send output to a stream at all.  So do nothing: don't
	 attempt to flush output; the drawing state [including
	 Plotter-specific data] has already been deleted, so there may not
	 be enough information to perform a flush.  This is an issue with
	 X Plotters in particular. */
      break;

    default:			/* shouldn't happen */
      break;
    }

  _plotter->data->open = false;	/* flag device as closed */

  if (retval1 == false || retval2 < 0)
    return -1;
  else return 0;
}

/* Plotter-specific teardowns and reinitializations that take place when
   closepl() is invoked.  In a generic Plotter, this does nothing. */

bool
#ifdef _HAVE_PROTOS
_g_end_page (S___(Plotter *_plotter))
#else
_g_end_page (S___(_plotter))
     S___(Plotter *_plotter;) 
#endif
{
  return true;
}

void
#ifdef _HAVE_PROTOS
_delete_first_drawing_state (S___(Plotter *_plotter))
#else
_delete_first_drawing_state (S___(_plotter))
     S___(Plotter *_plotter;) 
#endif
{
  /* elements of state that are strings or arrays are freed separately */
  free ((char *)_plotter->drawstate->fill_rule);
  free ((char *)_plotter->drawstate->line_mode);
  free ((char *)_plotter->drawstate->join_mode);
  free ((char *)_plotter->drawstate->cap_mode);
  free ((char *)_plotter->drawstate->true_font_name);
  free ((char *)_plotter->drawstate->font_name);

  /* free dash array too, if nonempty */
  if (_plotter->drawstate->dash_array_len > 0)
    free ((double *)_plotter->drawstate->dash_array);

  /* free the state itself */
  free (_plotter->drawstate);
  _plotter->drawstate = NULL;
}