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 176 177 178
|
/* This file is part of the GNU plotutils package. Copyright (C) 1995,
1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
The GNU plotutils package is free software. You may redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software foundation; either version 2, or (at your
option) any later version.
The GNU plotutils package is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along
with the GNU plotutils package; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
Boston, MA 02110-1301, USA. */
/* 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
_API_closepl (S___(Plotter *_plotter))
{
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 */
_pl_g_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
_pl_g_end_page (S___(Plotter *_plotter))
{
return true;
}
void
_pl_g_delete_first_drawing_state (S___(Plotter *_plotter))
{
/* 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;
}
|