home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume14 / vplot / part22 < prev    next >
Text File  |  1988-03-31  |  31KB  |  726 lines

  1. Subject:  v14i027:  Device-independant graphics system, with drivers
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Joe Dellinger <joe@hanauma.STANFORD.EDU>
  7. Posting-number: Volume 14, Issue 27
  8. Archive-name: vplot/part22
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 22 (of 24)."
  17. # Wrapped by rsalz@fig.bbn.com on Fri Mar 25 11:47:34 1988
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'Vplot_Kernel/Documentation/hacker.doc.2' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'Vplot_Kernel/Documentation/hacker.doc.2'\"
  21. else
  22. echo shar: Extracting \"'Vplot_Kernel/Documentation/hacker.doc.2'\" \(29413 characters\)
  23. sed "s/^X//" >'Vplot_Kernel/Documentation/hacker.doc.2' <<'END_OF_FILE'
  24. color 0. The box should be of the same color and fatness as the text.
  25. Which value of txovly corresponds to what action is defined in vplot.h.
  26. It is up to the device to decide how big a box around the text is
  27. appropriate for a given font. (It is probably a good idea to follow
  28. gentext's example in this.)
  29. X
  30. Pathx, pathy, upx, and upy define the size, shape, and orientation of
  31. the text. Pathx and upx are in HORIZONTAL device units, and pathy and upy
  32. are in VERTICAL device units. (This distinction is important if your device
  33. does not have aspect_ratio=1..) Note that all 4 values are FLOATS, not ints.
  34. X
  35. The vector (pathx,pathy) defines the text path, and the vector (upx,upy)
  36. defines the character up vector. (This is just like in the GKS text
  37. notation conventions.) To understand the meaning of these two vectors,
  38. consider normal horizontal text with a height of 100 pixels. (We'll
  39. assume our device has square pixels for the moment.)
  40. For this text, (pathx,pathy) = (100.,0.) and (upx,upy) = (0.,100.).
  41. Now the position of any point on this text can be expressed as
  42. a linear combination of the path vector and the up vector.
  43. This is how dev.text should represent all text internally.
  44. In this way, if we linearly transform just the path vector and
  45. the up vector, then we do the transform to every point of the text too.
  46. If we rotate both the path and up vectors, the text rotates.
  47. if we multiply both the path and up vectors by two, the text gets twice
  48. as big. If the path and up vectors are not orthogonal, the text gets
  49. sheared.
  50. X
  51. To test a device-dependent text routine, try switching between a
  52. device-dependent font and one of the gentext fonts (txfont<NUMGENFONT).
  53. If your device-dependent test routine is correctly working, the text
  54. should always appear the same as far as height, direction, and position
  55. in both cases.
  56. X
  57. Generic routines: gentext.c
  58. Gentext.c produces text by mixing vectors and filled areas. It calls
  59. dev.vector, dev.area, and dev.attributes. It also recognizes many
  60. special escape sequences in the text. Gentext is documented in vplottext(9).
  61. X
  62. X===========================
  63. X
  64. X#include "vertex.h"
  65. X#include "pat.h"
  66. dev.area(npts, verlist)
  67. int npts;
  68. struct vertex *verlist;
  69. X{
  70. X/* These can be defined by including extern.h */
  71. extern int xwmin, xwmax, ywmin, ywmax;
  72. extern int ipat;
  73. extern struct pat pat[];
  74. X
  75. Dev.area fills a polygon with a user-defined pattern. Npts is the number
  76. of vertices of the polygon. The coordinates of the vertices themselves
  77. are stored in the doubly linked list verlist.
  78. X
  79. Here is vertex.h:
  80. X
  81. struct vertex
  82. X{
  83. X    int x;                /* X coordinate of vertex */
  84. X    int y;                /* Y coordinate of vertex */
  85. X    struct vertex *next;        /* pointer to next vertex */
  86. X    struct vertex *last;        /* pointer to last vertex */
  87. X    struct vertex *soft;        /* pointer to some other vertex */
  88. X};
  89. X
  90. The coordinates are in device units. It is up to the device to clip
  91. the polygon! The lower-leftmost displayable point is (xwmin,ywmin) and
  92. the upper-rightmost displayable point is (xwmax,ywmax).
  93. X
  94. The pattern to fill with is given in the external pat[ipat], which is a
  95. structure of type pat.
  96. Here is pat.h:
  97. X
  98. struct pat
  99. X{
  100. X    int    ydim;                    /* Slow dimension */
  101. X    int    xdim;                    /* Fast dimension */
  102. X    int    ydim_orig;
  103. X    int    xdim_orig;
  104. X    int   patbits[/*xdim*ydim*/];    /* Array of color numbers */
  105. X};
  106. X
  107. Pat.patbits is an array of pat.xdim by pat.ydim color values, with
  108. one element in the array for each device pixel. The pattern is repeated
  109. to fill the polygon. The position of the origin of the pattern does not
  110. matter, but should not depend on the particular polygon. (In other words,
  111. if two polygons tiled with the same pattern overlap, the pattern should
  112. be continuous across the two.)
  113. X
  114. The horizontal dimension of the pattern is length pat.xdim. This is
  115. the fast axis. The vertical dimension of the pattern is length pat.ydim.
  116. This is the slow axis. The pattern is scanned on the screen TV-style.
  117. X(In other words, pat.patbits[0] is at the upper-left hand corner,
  118. pat.patbits[pat.xdim-1] is the upper-right hand corner, and
  119. pat.patbits[pat.ydim*pat.xdim-1] is the lower right hand corner.)
  120. X
  121. If either pat.xdim or pat.ydim is 0 for a given polygon, dev.area is
  122. never even called and so no filling is done. If your device cannot fill
  123. with an arbitrary pattern, it is OK to fill solidly with the current
  124. color instead.
  125. X
  126. Dovplot will use a 1 by 1 pattern for polygons generated by the
  127. VP_OLDAREA command if the device uses color, regardless of the requested
  128. pattern (this is part of the definition of the VP_OLDAREA command).
  129. XXdim_orig and ydim_orig contain the values that xdim and ydim would have
  130. had if the device had been black and white. This is provided so that
  131. no information needed to reconstruct the original vplot command is lost.
  132. X
  133. Dovplot will call dev.attributes(NEW_PAT,ipat) whenever the pattern
  134. defined by pat[ipat] is loaded or updated.
  135. X
  136. Generic routines: vecarea.c, genarea.c, genpatarea.c
  137. Vecarea fills the polygon with the current color by drawing vertical
  138. and horizontal vectors. It shows the size of the pattern by the line spacing.
  139. Vecarea calls dev.vector and dev.attributes.
  140. X
  141. Genarea clips the given polygon (if smart_clip=NO), possibly generating
  142. more than one polygon out of the pieces. It then calls dev.startpoly,
  143. dev.midpoly, and dev.endpoly to do the actual filling of the polygons.
  144. X
  145. Genpatarea fills the polygon with the correct pattern one raster line
  146. at a time by calling dev.raster. It uses the ``dumb'' format for
  147. dev.raster, so you cannot use genpatarea if smart_raster=YES.
  148. X
  149. X===========================
  150. X
  151. Dev.raster has 2 formats, depending on the value of smart_raster.
  152. X
  153. If smart_raster=NO, then the raster will be stretched to device
  154. coordinates, clipped (regardless of the value of smart_clip),
  155. color mapped, dithered (if appropriate), and broken up into individual
  156. scan lines. Dev.raster will be called once for each scan line of the
  157. raster image.
  158. X
  159. If smart_raster=YES, then the raster will be read in and color mapped,
  160. but nothing else. It is up to the device to dither it (if appropriate),
  161. stretch it, and clip it. The entire block of raster will be passed with
  162. one call to dev.raster.
  163. X
  164. X/* Dumb format, smart_raster=NO */
  165. dev.raster(count, out_of, xpos, ypos, rlength, orient, raster, dummy1, dummy2)
  166. int count, out_of, xpos, ypos, rlength, orient, dummy1, dummy2;
  167. unsigned char raster[/*rlength*/];
  168. X
  169. Draw a line of raster, starting at the point (xpos,ypos) and extending
  170. for a total of length pixels in a direction determined by orient.
  171. Orient is measured in units of 90 degrees clockwise from the device's
  172. XX (horizontal) axis. Thus for orient=0 you draw the line right,
  173. for orient=1 you draw down, for orient=2 left, and for orient=3 up.
  174. X
  175. The line of raster itself is in the array raster, which is of
  176. dimension rlength. Each element of the array is a color number which
  177. determines the color of one device pixel.
  178. X
  179. Some devices may be able to handle more than one line of raster at
  180. a time. The variables count and out_of are provided so that the device
  181. can know how many dev.raster calls will be made in a row. Count is
  182. zero for the first call, and increases by 1 each time until it reaches
  183. out_of-1 on the last call. (Thus out_of is the total number of raster
  184. lines.)
  185. X
  186. Scanning is done TV-style. (Thus, for orient=0, ypos decrements by 1
  187. for each call; for orient=1, xpos decrements by 1 for each call; for
  188. orient=2, ypos increments by 1 for each call; for orient=3, xpos
  189. increments by 1 for each call.) Genraster1 gives you a good example
  190. of how to write a routine that builds up blocks of raster over several
  191. calls.
  192. X
  193. Dummy1 and dummy2 are not used; they are provided only so that both forms
  194. of the command have the same string of arguments.
  195. X
  196. Generic routines, dumb format: genraster.c, genraster1.c
  197. Genraster does vector draws along scan lines to produce raster output.
  198. It does one raster line at a time. Some fast but stupid devices can
  199. actually do raster reasonably fast this way. Genraster calls
  200. dev.attributes (to set the colors) and dev.vector.
  201. X
  202. Genraster1 attempts to be a little smarter than genraster. It saves up
  203. many lines worth of raster at a time, and sorts the vectors by color
  204. and length. It does all the vectors of one color at a time, so as to
  205. save on calls to dev.attribute to change the color. It also finds
  206. the parts of the image that can be more efficiently drawn via dev.point,
  207. and makes a second pass for those. (If the device has a point mode this
  208. is considerably more efficient.) Genraster1 calls dev.attributes,
  209. dev.vector, and dev.point.
  210. X
  211. X/* Smart format, smart_raster=YES */
  212. dev.raster (xpix, ypix, xmin, ymin, xmax, ymax,
  213. X    raster_block, orient, dither_it)
  214. int xpix, ypix, xmin, ymin, xmax, ymax, orient, dither_it;
  215. unsigned char raster_block[/*xpix*ypix*/];
  216. X{
  217. X/* Including "extern.h" defines these. */
  218. extern int xwmin, xwmax, ywmin, ywmax;
  219. X
  220. Draw the block of raster in the array raster_block.
  221. If dither_it=NO, raster_block is an array of color numbers.
  222. If dither_it=YES, raster_block is an array of grey levels
  223. X(0 is black, 255 is white).
  224. X
  225. Raster_block has dimensions xpix times ypix, with xpix the fast
  226. axis. If orient=0, the raster is painted on the screen TV-style.
  227. The first array value is the upper-leftmost point. Each line of
  228. raster (xpix long) fills from left to right. Each new line of
  229. raster (ypix lines in all) is below the previous one.
  230. X
  231. If orient=1, we rotate the raster 90 degrees clockwise. Thus the
  232. first value is the upper rightmost point, and the raster fills in
  233. top to bottom and then right to left. For orient=2 we rotate another
  234. X90 degrees and fill in right to left and then bottom to top. For
  235. orient=3 we fill the raster in bottom to top and then left to right.
  236. X
  237. The lower-leftmost pixel in the raster image should appear on the screen
  238. at device coordinate (xmin, ymin) (assuming it isn't clipped, of course).
  239. The raster image should be (xmax-xmin) horizontal device units wide
  240. and (ymax-ymin) vertical device units tall. Thus, the pixel (xmax,ymax)
  241. is not the upper-rightmost pixel in the raster image, but is the first
  242. pixel above and to the right of the one that is. (I know this sounds
  243. strange. But when you actually code this up you'll see that it makes
  244. sense to do it this way, and that this is probably what you actually
  245. would have done even if I had told you to make sure that the point
  246. X(xmax,ymax) was in the image.)
  247. X
  248. Finally, the resulting image must be clipped so that (xwmin,ywmin) is
  249. the lower-leftmost pixel that can appear, and (xwmax,ywmax) is the
  250. upper-rightmost pixel that can appear. (Note that this time the corner
  251. IS in the image. Just trying to be confusing.)
  252. X
  253. Generic routines: NONE
  254. X
  255. X===========================
  256. X
  257. dev.point(x1, y1)
  258. int x1, y1;
  259. X
  260. Change the pixel at device coordinate (x1,y1) to the current color.
  261. X
  262. Generic routines: genpoint.c
  263. Genpoint calls dev.vector with zero length. Somethings wrong with
  264. the dev.vector for your device if it doesn't do anything in this case.
  265. X
  266. X===========================
  267. X
  268. dev.attributes(command, value, v1, v2, v3)
  269. int command, value, v1, v2, v3;
  270. X
  271. Set various attributes (color table, current color, clipping window, etc)
  272. using device-specific routines. Commands are defined and documented
  273. in include file attrcom.h. Value and v[1-3] are used to pass
  274. parameters as needed. Sometimes some of the 4 will be dummy arguments.
  275. X
  276. Comments about color:
  277. X    The device tells dovplot how many colors it has by setting num_col
  278. and mono. Num_col is the number of settable colors. The color for
  279. color table numbers num_col and up will never attempt to be defined
  280. by dovplot. If num_col is zero, the device has no settable colors,
  281. and dev.attributes(SET_COLOR_TABLE,...) will never be called at all.
  282. X
  283. X    Devices with no settable colors can still have color. If mono=NO,
  284. dovplot assumes that colors 0 through 7 correspond to the standard
  285. Vplot colors (as listed in vplot.h). Dovplot will not attempt to set
  286. the current color outside of the range 0 through 7 if num_col=0.
  287. X(There is no provision for devices with more than 8 colors but no
  288. settable colors.)
  289. X
  290. X    Rather than forcing people to change the colors on their terminal
  291. to have vplot's colors come out right, you should map the color numbers
  292. dovplot asks for onto the correct device color numbers so that the
  293. factory default setting gives the correct colors. (Don't forget to
  294. similarly map the color table numbers too.)
  295. X    
  296. X    Calls to dev.attributes(SET_COLOR,...) by dovplot will only set
  297. colors in the range 0 through MAX(7,num_col-1).
  298. X
  299. X    If mono=YES, dovplot will force num_col=0 and will only ever
  300. try to set the current color to be either 0 (meaning background)
  301. or 7 (meaning NOT background).
  302. X
  303. X    Calls to device routines should NEVER upset the current color. If
  304. for some reason they should change it, they should always put it back
  305. again when they are done. (Dovplot keeps track of the current color,
  306. and only calls dev.attributes(SET_COLOR,...) when necessary.) Calls to
  307. generic routines are guaranteed to never (permanently) change the
  308. current color.
  309. X
  310. X    Color tables should usually be set to factory default settings at
  311. the beginning of every plot, if it is possible to do this in such a
  312. way that the former settings can be restored again afterwards.
  313. X
  314. X    Every device should AT LEAST keep track of whether or not the current
  315. drawing color is color 0 or not. Color 0 always defines the background
  316. color. If the device cannot draw (or rather undraw) in the background
  317. color, then it SHOULDN'T DRAW AT ALL when the current color is 0.
  318. X
  319. Generic routines: NONE
  320. X
  321. X-------------------------------------------------------------
  322. X
  323. Input routines
  324. X
  325. X==============================
  326. X
  327. int dev.getpoint(termout, x, y)
  328. FILE *termout;
  329. int *x, *y;
  330. X{
  331. int status;
  332. X
  333. return status;
  334. X}
  335. X
  336. Turn on the cursor and let the user pick a point. Return the device
  337. coordinate of the picked point in (*x,*y), and return 0. If the
  338. user indicated that he doesn't want to pick any more points, return 1.
  339. X(The value in (*x,*y) is then considered to be junk by dovplot.)
  340. Returned values should be in the normal range of device coordinates.
  341. If (*x,*y) is returned unchanged, this will also indicate that no point
  342. was picked and no more points should be picked.
  343. X
  344. Termout is a stream pointer reading from ``/dev/tty''. You can use it if
  345. it is convenient and correct to do so, or ignore it.
  346. X
  347. Generic routines: nulldev
  348. Linking in nulldev for this routine will simulate a user that always
  349. declines to enter any points at all, since (*x,*y) is returned unchanged.
  350. X
  351. X==============================
  352. X
  353. dev.interact(command, termout, string)
  354. int command;
  355. FILE *termout;
  356. char string[];
  357. X
  358. This routine handles string input from the user and pausing.
  359. The various possible commands are described in
  360. X".../vplot/filters/include/intcom.h".
  361. X
  362. Generic routines: nulldev, geninteract
  363. Linking in nulldev will rudely zoom past all prompts to the user without
  364. waiting. This is a reasonable thing to do for hardcopy devices.
  365. X
  366. Geninteract will read the required input from termout, which is connected
  367. to read from "/dev/tty".
  368. X
  369. X--------------------------------------------------------------------------
  370. X
  371. Low level output routines --- only called by certain generic routines
  372. X
  373. X=================================
  374. X
  375. int lost = YES;
  376. dev.plot(x, y, draw)
  377. int x, y, draw;
  378. X
  379. Move or draw to device coordinate (x,y).
  380. Draw=0 for move, 1 for draw.
  381. X
  382. This routine MUST declare the global flag ``lost''. It is the responsibility
  383. of all the device routines to set this to YES whenever anything happens
  384. that may cause genvector's idea of the ``current device pen position''
  385. to be wrong.  (For example, printing an error message, doing hardware text,
  386. filling a polygon, etc.) Generic routines do not present a difficulty, since
  387. they can't output anything directly to the device.
  388. X
  389. When lost is set to YES, it is guaranteed that the next call to dev.plot
  390. will by a move, and not a draw.
  391. X
  392. When genvector's idea of the current position is correct again (for example
  393. when dev.plot has been called) lost should be set to NO. This is important;
  394. genvector only looks at the value of lost, it doesn't set it. Leaving
  395. lost YES all the time will greatly slow down plotting by forcing one move
  396. for each draw!
  397. X
  398. Generic routines: nulldev
  399. Link in nulldev here as a placeholder if you didn't use genvector as
  400. your vector routine.
  401. X
  402. X=================================
  403. X
  404. dev.startpoly(npts)
  405. int npts;
  406. X
  407. dev.midpoly(x,y)
  408. int x, y;
  409. X
  410. dev.endpoly(last)
  411. int last;
  412. X
  413. Polygon-drawing routines called only by genarea.
  414. X
  415. Dev.startpoly is called once at the beginning of every polygon.
  416. Npts gives the number of points in the polygon. After dev.startpoly
  417. has been called, then dev.midpoly is called once for each point in
  418. the polygon. (x,y) gives the device coordinate of the vertex.
  419. X
  420. Dev.endpoly is called once at the end of each polygon. Genarea may fragment
  421. one polygon into several. If this polygon just defined is the last polygon
  422. in a set of polygons that were fragmented from one, then last will be 1.
  423. If there are more fragments in this set to go, last will be 0. It is
  424. guaranteed that no other routines but these three will be called after
  425. the first dev.startpoly call and before dev.endpoly(last=YES) is called.
  426. X
  427. The genarea algorithm will fail for certain very complicated crossed
  428. polygons, unless the multiple polygons fragmented from the one original
  429. one are shaded as a unit. Some devices such as the Tek4105 allow this
  430. to be done. That is why the ``last'' flag is provided. There is no
  431. great harm in shading each polygon as it comes. Occasionally interior
  432. voids will be filled twice instead of not filled at all, that's all.
  433. X
  434. If the device can fill with an arbitrary pattern, it should do so.
  435. The pattern is available to these routines in the same way as described
  436. under dev.area. If the device cannot fill with a user-defined pattern,
  437. filling solidly with the current color is the next best thing.
  438. X
  439. Generic routines: nulldev.c
  440. If you did not use genarea as your dev.area routine, then none of
  441. these routines are ever called so you just need to put in nulldev
  442. as a placeholder.
  443. X
  444. X-------------------------------------------------------------------------
  445. HANDLING ERRORS:
  446. Device routines SHOULD NOT simply exit when they get a fatal error!
  447. All errors should be handled via the provided utility routine "ERR"!
  448. X
  449. X#include "err.h"
  450. ERR (type, filter, fmt, a1, a2, a3)
  451. int type;
  452. char *filter;
  453. char *fmt;
  454. double a1, a2, a3;
  455. X
  456. X"Type" is one of the possibilities from "err.h". Currently there are three
  457. possibilities: COMMENT, WARN, FATAL. Case COMMENT is just for making
  458. remarks, not really error messages per se. Case WARN should be used when
  459. something is wrong, but the filter can take reasonable corrective action.
  460. Case FATAL is for errors that should cause abnormal termination of the
  461. program. Calls to ERR with type FATAL will not return.
  462. X
  463. X"Filter" should be the name of the filter generating the error or comment
  464. as you want it to appear in the message. Normally this should just be
  465. the variable "name" defined in <dev>conf.c.
  466. X
  467. From here on ERR has the same syntax as "printf", except that ERR will
  468. automatically throw a carriage-return line-feed on for you (so you don't
  469. want to end with "\n").
  470. X
  471. After ERR has been called with type FATAL, dovplot and frontend will do
  472. necessary cleaning up, in the process calling dev.close. Device-dependent
  473. cleaning up should be done by that routine at that time.
  474. X
  475. The define ERR is used so that conflicts with other subroutines named
  476. X"error", "err", etc, can be avoided. Currently "ERR" is defined to be
  477. X"filtererror", a name we haven't had any trouble with.
  478. X
  479. X-------------------------------------------------------------------------
  480. BEING TRICKY ABOUT THE ORDER THINGS ARE PLOTTED
  481. X
  482. The external variable
  483. extern int (*genreader) ();
  484. can be changed in dev.open to point to your own routine for processing
  485. input files. You should only need to change this variable if for some
  486. reason you want to be able to change the order or way in which input files
  487. are handled, or if you want to know the actual file names of the input plot
  488. files. (You might find this handy if you are creating an interactive vplot
  489. editor, for example.)
  490. X
  491. The default input file handling routine, which is what you get if you
  492. ignore this section of the documentation, is the following. Frontend
  493. already does the job of finding all the input files, verifying that
  494. they exist, and opening them for reading.
  495. X
  496. gen_do_dovplot (nn, inpltin, innames)
  497. int     nn;
  498. FILE ** inpltin;
  499. char    innames[][MAXFLEN+1];
  500. X{
  501. X    int     ii;
  502. X
  503. X    for (ii = 0; ii < nn; ii++)
  504. X    {
  505. X    pltin = inpltin[ii];
  506. X    strcpy (pltname, innames[ii]);
  507. X    dovplot ();
  508. X    fclose (pltin);
  509. X    }
  510. X}
  511. X
  512. X"Nn" is the number of input files. "Inpltin" is an array of nn stream
  513. pointers each of which point to an open (but unread-upon) input stream.
  514. X"Innames" is the corresponding array of strings giving the associated
  515. name of the input file for each of the streams in inpltin.
  516. X
  517. The external integer "buffer_input" can be set to NO in dev.open to
  518. assure that all the input streams are unbuffered. The external integer
  519. X"allow_pipe" can be set to NO in dev.open to assure that all the input
  520. streams are seekable on.
  521. X
  522. It is possible to change most variables set by command line arguments
  523. between calls to dovplot without ill effect. There are comments in
  524. init_vplot at the end of the section of code where command line arguments
  525. are processed listing which variables have been explicitly set up to be
  526. changeable in this way.
  527. X
  528. Variables controlling the mapping between the device's and vplot's
  529. coordinate system can also be changed, but the subroutine
  530. X"reset_parameters()" in frontend must be called afterwards to
  531. reinitialize all the related variables that may need it.
  532. X
  533. X./filters/vplib/vpdovplot.c is an example of a routine that makes
  534. X2 passes through a vplot file, doing things differently the second
  535. time around.
  536. X
  537. X-------------------------------------------------------------------------
  538. THINGS THAT GET RESET BETWEEN FRAMES (AND THINGS THAT DON'T)
  539. X
  540. Vplot has many "global" parameters. Some of these get reset between
  541. frames (or between input files); a few don't.
  542. X
  543. The following parameters get reset (by reset()) at the start of
  544. every new frame:
  545. clipping windows, drawing fatness, current drawing color, text alignment
  546. mode, text font, text precision, text overlay mode, raster overlay mode,
  547. dash line pattern.
  548. X
  549. The plot style also gets reset at the start of every new frame, but
  550. it is handled separately.
  551. X
  552. The following DO NOT GET RESET AT ALL:
  553. color tables, current pen position
  554. X
  555. The global vplot origin command is another special case. Generally,
  556. this command is only used when you are creating a figure "by hand"
  557. using plas. It is reset when reset_parameters() is called, but is
  558. global otherwise. It has no libvplot command on purpose.
  559. X
  560. X-------------------------------------------------------------------------
  561. GROUPS
  562. X
  563. The begin-end group commands are provided so that a "MacDraw"-like
  564. vplot editor may be created. The device knows when groups are
  565. opened and closed, and their positions within the current plot file,
  566. via the dev.attributes(BEGIN_GROUP,...) and dev.attributes(END_GROUP,...)
  567. calls. You can use fseek to reposition the plot stream to the beginning
  568. of a desired group, and then call dovplot to plot the group again.
  569. When the group open (number one, not zero) command is processed, the device
  570. gets a chance to reset global attributes from their "initialized" values.
  571. X(For example, to change the color.) When the group close (number one)
  572. command is processed, the device gets a chance to to reposition pltin
  573. to the end of the file and so cause dovplot to think it's done and return.
  574. X
  575. It is possible for the user to violate the grouping laws, ie:
  576. begin-group and end-group commands must be paired within a file,
  577. erases may not be contained within a group.
  578. Dovplot will warn the user if this happens. How the device handles
  579. such an error, however, is up to it. Caveat user.
  580. X
  581. A group number 0 is generated by dovplot itself for each plot frame,
  582. and consists of everything in the plot frame excepting erases. Erases
  583. lie between groups. Initial erase and style commands are not contained
  584. in the first group numbered 0. Groups generated by the begin-end group
  585. commands in the vplot file are numbered from 1 on up.
  586. X
  587. The external integer "group_number" gives the number of currently
  588. open groups.
  589. X
  590. X-------------------------------------------------------------------------
  591. SEPLIB TRICKS
  592. X
  593. If you don't use the seplib versions of the filters, you can ignore
  594. this section.
  595. X
  596. Pen filters have to do some tricky things with SEPlib since the
  597. standard defaults are inappropriate. Normally seplib wants to send
  598. the header to standard out. Since the output of Pen filters are usually
  599. not redirected, this would dump the header on your screen and possibly
  600. interfere with your plot. By the same token, the data output usually
  601. SHOULD go to your screen, instead of being saved in a file or sent
  602. down a pipe. The normal SEPlib method of self-documenting also
  603. has to be subverted in order to be consistent between the SEP and non-SEP
  604. versions of the programs.
  605. X
  606. To accomplish this, several things are done:
  607. X
  608. A library "tseplib" is provided that contains routines for
  609. which the standard seplib versions had to be modified. This
  610. should be linked AHEAD of seplib so that the modified versions
  611. get taken. The routines are documented as to how they differ and why.
  612. X
  613. X"OUT" and "HEAD" are defined to be the external variables "sepoutwhere"
  614. and "sepheadwhere", respectively. These are normally "/dev/tty" and
  615. X"/dev/null". (These values are grabbed from the routine "sepwhere"
  616. in tseplib.) If these values are inappropriate for your filter (unlikely
  617. to be the case for most filters; see Vppen for an example of one) you can
  618. create your own version of this routine and make sure it gets linked in
  619. ahead of tseplib.
  620. X
  621. If head=/dev/null and this was the default in sepheadwhere and
  622. standard out is redirected, then it is assumed the user really wants
  623. some sort of header despite the fact that the Pen filter killed the
  624. real one and so a "fake" one will be created for them by frontend.
  625. Frontend will only actually write something into it if "out"
  626. is not standard out (to avoid mixing header and data). The
  627. device-dependent code may do so if it wishes, though (see Raspen for
  628. an example). The device should only use "Puthead" to write to the header,
  629. to make sure everything is done properly. The "fake" header has the
  630. advantage that information can be added to it at any time.
  631. Normal SEPlib headers must be closed before any data can be written.
  632. Thus only fake headers can have "n3=number_of_frames" added onto
  633. the header. (This is why Raspen uses fake headers.)
  634. X
  635. X-------------------------------------------------------------------------
  636. FRONTEND, and DOING IT YOURSELF
  637. X
  638. The system-user interface is split among three routines, which together
  639. are called the "frontend".
  640. X
  641. Main_vplot is responsible for finding the input files and opening them,
  642. deciding where the output should go for devices that aren't strong-willed
  643. enough to insist on figuring it out for themselves, setting up signal
  644. catching, interfacing with SEPlib, and doing self-documentation.
  645. It also calls the other 2 routines, init_vplot and proc_vplot.
  646. X
  647. Init_vplot initializes all variables and calls dev.open to open the
  648. device.
  649. X
  650. Proc_vplot processes the input files.
  651. X
  652. It is possible to skip main_vplot and call init_vplot and proc_vplot
  653. yourself directly. However, init_vplot and proc_vplot expect certain
  654. things to be set before they are called.
  655. X
  656. Init_vplot expects:
  657. X
  658. XXargc and xargv are just copies of main's argc and argv, but declared
  659. globally so that other routines (namely getpar) have access to them.
  660. XXargc and xargv should be declared in the calling program.
  661. X
  662. Callname is a string which gives the "pen filter name" of the set of
  663. device-dependent routines you want. It should have the path stripped.
  664. The device-dependent code may want to know callname in order to pick
  665. between similar devices. Callname should be declared external.
  666. X
  667. Pltout is just a copy of stdout. It is an external FILE *.
  668. X
  669. Proc_vplot expects:
  670. X
  671. Infileno gives the number of input files. It is an external integer.
  672. X
  673. Pltinname[infileno] gives the names of the input files. It is
  674. an external array of pointers to chars.
  675. X
  676. Pltinarray[infileno] gives the already-open stream pointers for the
  677. afore-mentioned files. It is an external array of FILE *'s.
  678. X
  679. That's it.
  680. It is also possible to bypass even calling proc_vplot. See sample.c
  681. in .../vplot/filters for an example of how to do this.
  682. X
  683. X-------------------------------------------------------------------------
  684. AUTHORS
  685. The present generation of pen filters were created by Joe Dellinger.
  686. The original pen programs were written by Jeff Thorson and Rob Clayton.
  687. Glenn Kroeger and Michel Debiche cleaned up the organization of the code.
  688. Wes Monroe, Chuck Karish, Rick Ottolini, Doug Wilson, and Jean-Luc Guiziou
  689. have added support for new devices. Steve Cole added dithering. Stew Levin
  690. has found and fixed obscure bugs.
  691. X
  692. COPYRIGHT
  693. Vplot is copyrighted. Please read the copyright in the accompanying
  694. X"Vplot" manual page. The copyright is not very restrictive. If you
  695. want to include vplot (or derivatives thereof) as part of some other
  696. X"public domain" or "nearly public domain" package, we can probably
  697. work something out. The desired effect of the copyright is to permit
  698. widespread distribution without somebody trying to grab control of
  699. it for themselves or trying to sell it.
  700. X
  701. SEE ALSO
  702. vplot(L) pen(L) plas(L) pldb(L) seplib(L) getpar(L)
  703. END_OF_FILE
  704. if test 29413 -ne `wc -c <'Vplot_Kernel/Documentation/hacker.doc.2'`; then
  705.     echo shar: \"'Vplot_Kernel/Documentation/hacker.doc.2'\" unpacked with wrong size!
  706. fi
  707. # end of 'Vplot_Kernel/Documentation/hacker.doc.2'
  708. fi
  709. echo shar: End of archive 22 \(of 24\).
  710. cp /dev/null ark22isdone
  711. MISSING=""
  712. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ; do
  713.     if test ! -f ark${I}isdone ; then
  714.     MISSING="${MISSING} ${I}"
  715.     fi
  716. done
  717. if test "${MISSING}" = "" ; then
  718.     echo You have unpacked all 24 archives.
  719.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  720. else
  721.     echo You still need to unpack the following archives:
  722.     echo "        " ${MISSING}
  723. fi
  724. ##  End of shell archive.
  725. exit 0
  726.