x_savestate.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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 push_state() and pop_state() for XDrawablePlotters
  16. (and XPlotters). They supplement the generic behavior of savestate()
  17. and restorestate(), which create and destroy drawing states on the
  18. stack. push_state() constructs X11 GC's (i.e. graphics contexts) for a
  19. new drawing state. We copy into them, from each of the current GC's,
  20. all attributes we're interested in. pop_state() tears down the GC's. */
  21. #include "sys-defines.h"
  22. #include "extern.h"
  23. void
  24. _pl_x_push_state (S___(Plotter *_plotter))
  25. {
  26. Drawable drawable;
  27. XGCValues gcv;
  28. /* create the X-specified drawing state elements that are pointers (e.g.,
  29. GC's or lists) */
  30. /* determine which if either drawable we'll construct the GC's for */
  31. if (_plotter->x_drawable1)
  32. drawable = _plotter->x_drawable1;
  33. else if (_plotter->x_drawable2)
  34. drawable = _plotter->x_drawable2;
  35. else
  36. drawable = (Drawable)NULL;
  37. if (drawable != (Drawable)NULL)
  38. /* prepare GC's for new drawing state, by copying attributes we use */
  39. {
  40. unsigned long gcmask_fg, gcmask_fill, gcmask_bg;
  41. gcmask_fg =
  42. /* constant attributes (never altered) */
  43. GCPlaneMask | GCFunction
  44. /* drawing attributes set by _pl_x_set_attributes() */
  45. /* NOTE: we also use GCDashOffset and GCDashList, but Xlib does not
  46. support retrieving the dash list from a GC, so we'll copy the
  47. dashing style in another (painful) way */
  48. | GCLineStyle | GCLineWidth | GCJoinStyle | GCCapStyle
  49. /* other GC elements set by the X Drawable driver */
  50. | GCForeground | GCFont;
  51. gcmask_fill =
  52. /* constant attributes (never altered) */
  53. GCPlaneMask | GCFunction | GCArcMode
  54. /* filling attributes set by _pl_x_set_attributes() */
  55. | GCFillRule
  56. /* other GC elements set by the X Drawable driver */
  57. | GCForeground;
  58. gcmask_bg =
  59. /* constant attributes (never altered) */
  60. GCPlaneMask | GCFunction
  61. /* other GC elements set by the X Drawable driver */
  62. | GCForeground;
  63. /* copy from previous drawing state */
  64. /* copy GC used for drawing */
  65. XGetGCValues (_plotter->x_dpy, _plotter->drawstate->previous->x_gc_fg,
  66. gcmask_fg, &gcv);
  67. _plotter->drawstate->x_gc_fg = XCreateGC (_plotter->x_dpy, drawable,
  68. gcmask_fg, &gcv);
  69. if (gcv.line_style != LineSolid)
  70. /* copy dash style info from previous state */
  71. {
  72. int i, dash_list_len;
  73. char *dash_list;
  74. /* add dash style elements to GC used for drawing */
  75. XSetDashes (_plotter->x_dpy, _plotter->drawstate->x_gc_fg,
  76. _plotter->drawstate->previous->x_gc_dash_offset,
  77. _plotter->drawstate->previous->x_gc_dash_list,
  78. _plotter->drawstate->previous->x_gc_dash_list_len);
  79. /* add non-opaque dash style elements */
  80. dash_list_len =
  81. _plotter->drawstate->previous->x_gc_dash_list_len;
  82. dash_list = (char *)_pl_xmalloc (dash_list_len * sizeof(char));
  83. for (i = 0; i < dash_list_len; i++)
  84. dash_list[i] =
  85. _plotter->drawstate->previous->x_gc_dash_list[i];
  86. _plotter->drawstate->x_gc_dash_list = dash_list;
  87. /* these two were already added by the copy operation that took
  88. place in _g_savestate(), but we'll add them again */
  89. _plotter->drawstate->x_gc_dash_list_len = dash_list_len;
  90. _plotter->drawstate->x_gc_dash_offset =
  91. _plotter->drawstate->previous->x_gc_dash_offset;
  92. }
  93. else
  94. {
  95. _plotter->drawstate->x_gc_dash_list = (char *)NULL;
  96. _plotter->drawstate->x_gc_dash_list_len = 0;
  97. _plotter->drawstate->x_gc_dash_offset = 0;
  98. }
  99. /* copy GC used for filling */
  100. XGetGCValues (_plotter->x_dpy, _plotter->drawstate->previous->x_gc_fill,
  101. gcmask_fill, &gcv);
  102. _plotter->drawstate->x_gc_fill = XCreateGC (_plotter->x_dpy, drawable,
  103. gcmask_fill, &gcv);
  104. /* copy GC used for erasing */
  105. XGetGCValues (_plotter->x_dpy, _plotter->drawstate->previous->x_gc_bg,
  106. gcmask_bg, &gcv);
  107. _plotter->drawstate->x_gc_bg = XCreateGC (_plotter->x_dpy, drawable,
  108. gcmask_bg, &gcv);
  109. }
  110. }
  111. void
  112. _pl_x_pop_state (S___(Plotter *_plotter))
  113. {
  114. /* N.B. we do _not_ free _plotter->drawstate->x_font_struct anywhere,
  115. when restorestate() is invoked on an X Drawable or X Plotter */
  116. /* Free graphics contexts, if we have them -- and to have them, must have
  117. at least one drawable (see _pl_x_push_state()). */
  118. if (_plotter->x_drawable1 || _plotter->x_drawable2)
  119. {
  120. /* free the dash list in the X11-specific part of the drawing state */
  121. if (_plotter->drawstate->x_gc_dash_list_len > 0
  122. && _plotter->drawstate->x_gc_dash_list != (char *)NULL)
  123. free ((char *)_plotter->drawstate->x_gc_dash_list);
  124. XFreeGC (_plotter->x_dpy, _plotter->drawstate->x_gc_fg);
  125. XFreeGC (_plotter->x_dpy, _plotter->drawstate->x_gc_fill);
  126. XFreeGC (_plotter->x_dpy, _plotter->drawstate->x_gc_bg);
  127. }
  128. }