t_tek_vec.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 low-level _pl_t_tek_vector() method, which takes
  16. two integer arguments and writes them, in the format used by a Tektronix
  17. 4014 terminal for addresses while in vector or point-plot mode, to a
  18. specified output stream. It is called by several TekPlotter methods.
  19. Original Tek 4014 resolution was 1024 by 1024, with 1024 by 780
  20. displayable, i.e. 0x400 by 0x30c. Extended (EGM) resolution, supported
  21. by 4014's with the Enhanced Graphics Module, is four times that: 4096 by
  22. 3120. This is the resolution of the xterm Tektronix emulator.
  23. With EGM, have an allowed range of 12 bits (0 <= x,y <=4095). A Tek
  24. code for a point address (x,y) consists of a sequence of bytes:
  25. [Hi_Y] [EGM] [Lo_Y] [Hi_X] Lo_X.
  26. Since the EGM byte was added later, to improve resolution, it contains
  27. the lowest 2 bits of each of the X and Y bytes, packed into the lowest
  28. four bits of the byte. The remaining 10 bits are subdivided as follows
  29. among the remaining four code bytes. Lo=lowest 5 of the 10 bits,
  30. Hi=highest 5 of the 10 bits, all packed into the lowest 5 bits of the
  31. byte. Code bytes are distinguished from each other by the pattern of
  32. the high three bits. (Hi_Y = ?01, EGM = ?11, Lo_Y = ?11, Hi_X = ?01,
  33. Lo_X = ?10, where ? is ignored [or should be].) If EGM is included then
  34. Lo_Y must be included to prevent ambiguity. Also if Hi_X is included
  35. then Lo_Y must be included.
  36. If a byte is omitted, then its value defaults to the value of the
  37. corresponding byte in the most recently received point. The exception
  38. is the EGM byte; if omitted, it defaults to zero.
  39. Warning: some emulators, the xterm emulator in particular, get this
  40. scheme wrong. The xterm emulator will behave unpredicably if Lo_Y is
  41. omitted. And if EGM is omitted, its value (as far as the xterm emulator
  42. goes) is not zero, but is equal to the value of the EGM byte in the most
  43. recently received point. */
  44. #include "sys-defines.h"
  45. #include "extern.h"
  46. #define FIVEBITS 0x1F
  47. #define TWOBITS 0x03 /* a dollar and six bits for a haircut... */
  48. void
  49. _pl_t_tek_vector (R___(Plotter *_plotter) int xx, int yy)
  50. {
  51. unsigned char xx_high, yy_high;
  52. unsigned char xx_low, yy_low;
  53. unsigned char xx_topsig, yy_topsig;
  54. unsigned char egm;
  55. unsigned char byte_buf[5];
  56. int num_bytes = 0;
  57. #ifdef NO_WRAP /* could completely restrict to box */
  58. if (xx < 0)
  59. xx = 0;
  60. if (yy < 0)
  61. yy = 0;
  62. #endif
  63. xx_high = (xx>>7) & FIVEBITS; /* bits 11 through 7 of xx */
  64. yy_high = (yy>>7) & FIVEBITS; /* bits 11 through 7 of yy */
  65. xx_low = (xx>>2) & FIVEBITS; /* bits 6 through 2 of xx */
  66. yy_low = (yy>>2) & FIVEBITS; /* bits 6 through 2 of yy */
  67. xx_topsig = xx & TWOBITS; /* bits 1 through 0 of xx */
  68. yy_topsig = yy & TWOBITS; /* bits 1 through 0 of yy */
  69. egm = (yy_topsig<<2) + xx_topsig;
  70. /* The bit patterns 0x20, 0x40, 0x60 are magic */
  71. byte_buf[num_bytes++] = yy_high | 0x20; /* bits 5 through 9 of yy */
  72. #ifdef CAN_OMIT_EGM
  73. if (egm)
  74. #endif
  75. byte_buf[num_bytes++] = egm | 0x60;
  76. byte_buf[num_bytes++] = yy_low | 0x60; /* bits 0 through 4 of yy */
  77. byte_buf[num_bytes++] = xx_high | 0x20; /* bits 5 through 9 of xx */
  78. byte_buf[num_bytes++] = xx_low | 0x40; /* bits 0 through 4 of xx */
  79. /* invoke low-level output routine */
  80. _write_bytes (_plotter->data, num_bytes, byte_buf);
  81. return;
  82. }
  83. /* This version checks whether the supplied x and y coordinates are similar
  84. to the x and y coordinates of another point, presumed to be the most
  85. recently output point. If they are, the Tek code is shortened by the
  86. omission of optional bytes. Hi_Y, Lo_Y and Hi_X are all held in memory,
  87. so need not be transmitted if they did not change. Lo_X must always be
  88. transmitted. EGM is not held in memory; if not transmitted, it defaults
  89. to zero.
  90. The `force' argument will force output even if the vector has zero
  91. length. */
  92. void
  93. _pl_t_tek_vector_compressed (R___(Plotter *_plotter) int xx, int yy, int oldxx, int oldyy, bool force)
  94. {
  95. unsigned char xx_high, yy_high, oldxx_high, oldyy_high;
  96. unsigned char xx_low, yy_low, oldyy_low;
  97. unsigned char xx_top, yy_top;
  98. unsigned char egm;
  99. unsigned char byte_buf[5];
  100. int num_bytes = 0;
  101. #ifdef NO_WRAP /* could completely restrict to box */
  102. if (xx < 0)
  103. xx = 0;
  104. if (yy < 0)
  105. yy = 0;
  106. #endif
  107. /* if line segment has zero length, do nothing unless forcing an output */
  108. if (!force && (xx == oldxx) && (yy == oldyy))
  109. return;
  110. xx_high = (xx>>7) & FIVEBITS; /* bits 11 through 7 of xx */
  111. yy_high = (yy>>7) & FIVEBITS; /* bits 11 through 7 of yy */
  112. oldxx_high = (oldxx>>7) & FIVEBITS; /* bits 11 through 7 of oldxx */
  113. oldyy_high = (oldyy>>7) & FIVEBITS; /* bits 11 through 7 of oldyy */
  114. xx_low = (xx>>2) & FIVEBITS; /* bits 6 through 2 of xx */
  115. yy_low = (yy>>2) & FIVEBITS; /* bits 6 through 2 of yy */
  116. oldyy_low = (oldyy>>2) & FIVEBITS; /* bits 4 through 0 of oldyy */
  117. xx_top = xx & TWOBITS; /* bits 1 through 0 of xx */
  118. yy_top = yy & TWOBITS; /* bits 1 through 0 of yy */
  119. egm = (yy_top<<2) + xx_top;
  120. /* The bit patterns 0x20, 0x40, 0x60 are magic */
  121. if (yy_high != oldyy_high)
  122. byte_buf[num_bytes++] = yy_high | 0x20; /* bits 11 through 7 of yy: Hi_Y */
  123. #ifdef CAN_OMIT_EGM
  124. if (egm)
  125. #endif
  126. byte_buf[num_bytes++] = egm | 0x60; /* bits 1 through 0 of xx and yy */
  127. #ifdef CAN_OMIT_LO_Y
  128. if ((yy_low != oldyy_low) || (xx_high != oldxx_high) || egm)
  129. #endif
  130. byte_buf[num_bytes++] = yy_low | 0x60; /* bits 6 through 2 of yy: Lo_Y */
  131. if (xx_high != oldxx_high)
  132. byte_buf[num_bytes++] = xx_high | 0x20; /* bits 11 through 7 of xx: Hi_X */
  133. byte_buf[num_bytes++] = xx_low | 0x40; /* bits 6 through 2 of xx: Lo_X */
  134. /* invoke low-level output routine */
  135. _write_bytes (_plotter->data, num_bytes, byte_buf);
  136. return;
  137. }