g_closepl.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* This file is part of the GNU plotutils package. Copyright (C) 1995,
  2. 1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
  3. The GNU plotutils package is free software. You may redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software foundation; either version 2, or (at your
  6. option) any later version.
  7. The GNU plotutils package is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with the GNU plotutils package; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  14. Boston, MA 02110-1301, USA. */
  15. /* This file contains the closepl method, which is a standard part of
  16. libplot. It closes a Plotter object. */
  17. /* This generic version does only basic mechanics, since GenericPlotters
  18. don't emit any graphics code. */
  19. #include "sys-defines.h"
  20. #include "extern.h"
  21. int
  22. _API_closepl (S___(Plotter *_plotter))
  23. {
  24. bool emit_not_just_the_first_page = true;
  25. bool retval1;
  26. int retval2 = 0;
  27. if (!_plotter->data->open)
  28. {
  29. _plotter->error (R___(_plotter)
  30. "closepl: invalid operation");
  31. return -1;
  32. }
  33. _API_endpath (S___(_plotter)); /* flush path if any */
  34. /* pop drawing states in progress, if any, off the stack */
  35. if (_plotter->drawstate->previous != NULL)
  36. {
  37. while (_plotter->drawstate->previous)
  38. _API_restorestate (S___(_plotter));
  39. }
  40. /* invoke Plotter-specific method to end the page; also do
  41. device-dependent teardown Plotter-specific drawing state variables, do
  42. reinitialization of Plotter-specific Plotter variables, and create
  43. page header and trailer if any */
  44. retval1 = _plotter->end_page (S___(_plotter));
  45. /* remove first drawing state too, so we can start afresh */
  46. _pl_g_delete_first_drawing_state (S___(_plotter));
  47. switch ((int)_plotter->data->output_model)
  48. {
  49. case (int)PL_OUTPUT_NONE:
  50. /* we don't do output, so just delete the page buffer (presumably it
  51. includes neither a header nor a trailer) */
  52. if (_plotter->data->page)
  53. _delete_outbuf (_plotter->data->page);
  54. _plotter->data->page = (plOutbuf *)NULL;
  55. break;
  56. case (int)PL_OUTPUT_ONE_PAGE:
  57. emit_not_just_the_first_page = false;
  58. /* fall through */
  59. case (int)PL_OUTPUT_ONE_PAGE_AT_A_TIME:
  60. if (_plotter->data->page
  61. && (emit_not_just_the_first_page
  62. || _plotter->data->page_number == 1))
  63. {
  64. /* emit page header if any */
  65. if (_plotter->data->page->header
  66. && _plotter->data->page->header->len > 0)
  67. _write_string (_plotter->data,
  68. _plotter->data->page->header->base);
  69. /* emit all the graphics on the page */
  70. if (_plotter->data->page && _plotter->data->page->len > 0)
  71. _write_string (_plotter->data, _plotter->data->page->base);
  72. /* emit page trailer if any */
  73. if (_plotter->data->page->trailer
  74. && _plotter->data->page->trailer->len > 0)
  75. _write_string (_plotter->data,
  76. _plotter->data->page->trailer->base);
  77. /* attempt to flush (will test whether stream is jammed) */
  78. retval2 = _API_flushpl (S___(_plotter));
  79. }
  80. /* delete page header if any */
  81. if (_plotter->data->page->header)
  82. _delete_outbuf (_plotter->data->page->header);
  83. _plotter->data->page->header = (plOutbuf *)NULL;
  84. /* delete page trailer if any */
  85. if (_plotter->data->page->trailer)
  86. _delete_outbuf (_plotter->data->page->trailer);
  87. _plotter->data->page->trailer = (plOutbuf *)NULL;
  88. /* delete page's plOutbuf */
  89. if (_plotter->data->page)
  90. _delete_outbuf (_plotter->data->page);
  91. _plotter->data->page = (plOutbuf *)NULL;
  92. break;
  93. case (int)PL_OUTPUT_PAGES_ALL_AT_ONCE:
  94. /* Plotter will do its own output, in its terminate() routine.
  95. It will do so by writing out the contents of all its cached pages
  96. (a new one gets added to the list each time openpl() is invoked).
  97. So do nothing. */
  98. break;
  99. case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES:
  100. case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES_IN_REAL_TIME:
  101. /* Plotter does its own output, and doesn't use libplot's
  102. plOutbuf-based output system. So do nothing, except
  103. attempt to flush (will test whether stream is jammed) */
  104. retval2 = _API_flushpl (S___(_plotter));
  105. break;
  106. case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES_TO_NON_STREAM:
  107. /* Plotter doesn't use libplot's plOutbuf-based output system, and in
  108. fact doesn't send output to a stream at all. So do nothing: don't
  109. attempt to flush output; the drawing state [including
  110. Plotter-specific data] has already been deleted, so there may not
  111. be enough information to perform a flush. This is an issue with
  112. X Plotters in particular. */
  113. break;
  114. default: /* shouldn't happen */
  115. break;
  116. }
  117. _plotter->data->open = false; /* flag device as closed */
  118. if (retval1 == false || retval2 < 0)
  119. return -1;
  120. else return 0;
  121. }
  122. /* Plotter-specific teardowns and reinitializations that take place when
  123. closepl() is invoked. In a generic Plotter, this does nothing. */
  124. bool
  125. _pl_g_end_page (S___(Plotter *_plotter))
  126. {
  127. return true;
  128. }
  129. void
  130. _pl_g_delete_first_drawing_state (S___(Plotter *_plotter))
  131. {
  132. /* elements of state that are strings or arrays are freed separately */
  133. free ((char *)_plotter->drawstate->fill_rule);
  134. free ((char *)_plotter->drawstate->line_mode);
  135. free ((char *)_plotter->drawstate->join_mode);
  136. free ((char *)_plotter->drawstate->cap_mode);
  137. free ((char *)_plotter->drawstate->true_font_name);
  138. free ((char *)_plotter->drawstate->font_name);
  139. /* free dash array too, if nonempty */
  140. if (_plotter->drawstate->dash_array_len > 0)
  141. free ((double *)_plotter->drawstate->dash_array);
  142. /* free the state itself */
  143. free (_plotter->drawstate);
  144. _plotter->drawstate = NULL;
  145. }