conv_gb.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #ifdef PLAN9
  10. #include <u.h>
  11. #include <libc.h>
  12. #include <bio.h>
  13. #else
  14. #include <stdio.h>
  15. #include <unistd.h>
  16. #include "plan9.h"
  17. #endif
  18. #include "hdr.h"
  19. #include "conv.h"
  20. #include "gb.h"
  21. /*
  22. a state machine for interpreting gb.
  23. */
  24. void
  25. gbproc(int c, Rune **r, long input_loc)
  26. {
  27. static enum { state0, state1 } state = state0;
  28. static int lastc;
  29. long n, ch, cold = c;
  30. switch(state)
  31. {
  32. case state0: /* idle state */
  33. if(c < 0)
  34. return;
  35. if(c >= 0xA1){
  36. lastc = c;
  37. state = state1;
  38. return;
  39. }
  40. emit(c);
  41. return;
  42. case state1: /* seen a font spec */
  43. if(c >= 0xA1)
  44. n = (lastc-0xA0)*100 + (c-0xA0);
  45. else {
  46. nerrors++;
  47. if(squawk)
  48. EPR "%s: bad gb glyph %d (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, c-0xA0, lastc, cold, input_loc, file);
  49. if(!clean)
  50. emit(BADMAP);
  51. state = state0;
  52. return;
  53. }
  54. ch = tabgb[n];
  55. if(ch < 0){
  56. nerrors++;
  57. if(squawk)
  58. EPR "%s: unknown gb %ld (from 0x%x,0x%lx) near byte %ld in %s\n", argv0, n, lastc, cold, input_loc, file);
  59. if(!clean)
  60. emit(BADMAP);
  61. } else
  62. emit(ch);
  63. state = state0;
  64. }
  65. }
  66. void
  67. gb_in(int fd, int32_t *notused, struct convert *out)
  68. {
  69. Rune ob[N];
  70. Rune *r, *re;
  71. uint8_t ibuf[N];
  72. int n, i;
  73. int32_t nin;
  74. USED(notused);
  75. r = ob;
  76. re = ob+N-3;
  77. nin = 0;
  78. while((n = read(fd, ibuf, sizeof ibuf)) > 0){
  79. for(i = 0; i < n; i++){
  80. gbproc(ibuf[i], &r, nin++);
  81. if(r >= re){
  82. OUT(out, ob, r-ob);
  83. r = ob;
  84. }
  85. }
  86. if(r > ob){
  87. OUT(out, ob, r-ob);
  88. r = ob;
  89. }
  90. }
  91. gbproc(-1, &r, nin);
  92. if(r > ob)
  93. OUT(out, ob, r-ob);
  94. OUT(out, ob, 0);
  95. }
  96. void
  97. gb_out(Rune *base, int n, long *notused)
  98. {
  99. char *p;
  100. int i;
  101. Rune r;
  102. static int first = 1;
  103. USED(notused);
  104. if(first){
  105. first = 0;
  106. for(i = 0; i < NRUNE; i++)
  107. tab[i] = -1;
  108. for(i = 0; i < GBMAX; i++)
  109. if(tabgb[i] != -1)
  110. tab[tabgb[i]] = i;
  111. }
  112. nrunes += n;
  113. p = obuf;
  114. for(i = 0; i < n; i++){
  115. r = base[i];
  116. if(r < 128)
  117. *p++ = r;
  118. else {
  119. if(tab[r] != -1){
  120. r = tab[r];
  121. *p++ = 0xA0 + (r/100);
  122. *p++ = 0xA0 + (r%100);
  123. continue;
  124. }
  125. if(squawk)
  126. EPR "%s: rune 0x%x not in output cs\n", argv0, r);
  127. nerrors++;
  128. if(clean)
  129. continue;
  130. *p++ = BYTEBADMAP;
  131. }
  132. }
  133. noutput += p-obuf;
  134. if(p > obuf)
  135. write(1, obuf, p-obuf);
  136. }