utils.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package main
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "os"
  6. "red-green/door"
  7. "strings"
  8. )
  9. func ListFonts(filename string) {
  10. f, err := os.Open(filename)
  11. if err != nil {
  12. fmt.Printf("Open(%s): %s\n", filename, err)
  13. panic(err)
  14. }
  15. defer f.Close()
  16. fmt.Println(filename, ":")
  17. tdfonts := make([]byte, 20)
  18. f.Read(tdfonts)
  19. for {
  20. fontdef := make([]byte, 4)
  21. read, _ := f.Read(fontdef)
  22. if read != 4 {
  23. break
  24. }
  25. fontname := make([]byte, 13)
  26. f.Read(fontname)
  27. Name := strings.Trim(string(fontname[1:]), "\x00")
  28. // fmt.Printf("Font: %s\n", Name)
  29. f.Read(fontdef)
  30. single := make([]byte, 1)
  31. var FontType int8
  32. binary.Read(f, binary.LittleEndian, &FontType)
  33. // f.Read(single) // FontType
  34. // FontType := int(single[0])
  35. fmt.Printf("Font: %s (type %d)\n", Name, FontType)
  36. f.Read(single) // Spacing
  37. // blocksize := make([]byte, 2)
  38. // f.Read(blocksize)
  39. var BlockSize int16
  40. binary.Read(f, binary.LittleEndian, &BlockSize)
  41. // fmt.Printf("Size: %d / %x\n", BlockSize, BlockSize)
  42. letterOffsets := make([]int16, 94)
  43. binary.Read(f, binary.LittleEndian, &letterOffsets)
  44. if false {
  45. for idx, i := range letterOffsets {
  46. fmt.Printf(" %04X", i)
  47. if (idx+1)%10 == 0 {
  48. fmt.Println("")
  49. }
  50. }
  51. fmt.Println("")
  52. }
  53. data := make([]byte, BlockSize)
  54. binary.Read(f, binary.LittleEndian, &data)
  55. }
  56. }
  57. func byte_to_text(line []byte) string {
  58. var output string
  59. for _, ch := range line {
  60. output += fmt.Sprintf("0x%02x, ", ch)
  61. }
  62. if len(output) > 0 {
  63. output = output[:len(output)-2]
  64. }
  65. return output
  66. }
  67. /*
  68. func text_to_hextext(line string) string {
  69. var output string
  70. // output = "\""
  71. for _, ch := range []byte(line) {
  72. // output += fmt.Sprintf("\\x%02x", ch)
  73. output += fmt.Sprintf("0x%02x,", ch)
  74. }
  75. if len(output) > 1 {
  76. output = output[:len(output)-1]
  77. }
  78. // output += "\""
  79. return output
  80. }
  81. */
  82. func ExtractColor(name string, offsets []uint16, data []byte) (Font door.ColorFont) {
  83. defer func() {
  84. if r := recover(); r != nil {
  85. // Ok, this failed
  86. Font = door.ColorFont{}
  87. }
  88. }()
  89. var indexes []int
  90. var blocks [][][]byte
  91. var current [][]byte
  92. var line []byte
  93. pos := 0
  94. for pos < len(data) {
  95. indexes = append(indexes, pos)
  96. current = make([][]byte, 0)
  97. line = make([]byte, 0)
  98. // We don't use these.
  99. // w = data[pos]
  100. // h = data[pos+1]
  101. pos += 2
  102. // process this character
  103. for pos < len(data) {
  104. ch := data[pos]
  105. pos++
  106. if ch == 0x00 {
  107. // end of character
  108. current = append(current, line)
  109. blocks = append(blocks, current)
  110. // current = make([][]byte, 0)
  111. // line = make([]byte, 0)
  112. break
  113. }
  114. if ch == 0x0d {
  115. // end of this character line
  116. current = append(current, line)
  117. line = make([]byte, 0)
  118. continue
  119. }
  120. if ch == 0x26 {
  121. // & descender mark
  122. continue
  123. }
  124. line = append(line, ch)
  125. color := data[pos]
  126. pos++
  127. line = append(line, color)
  128. }
  129. }
  130. // offset optimization:
  131. var single []int
  132. for _, o := range offsets {
  133. if o == 65535 {
  134. single = append(single, -1)
  135. continue
  136. }
  137. found := false
  138. for idx, i := range indexes {
  139. if o == uint16(i) {
  140. single = append(single, idx)
  141. found = true
  142. break
  143. }
  144. }
  145. if !found {
  146. panic(fmt.Sprintf("Unable to locate index %d / %x (font appears corrupted)", o, o))
  147. }
  148. }
  149. return door.ColorFont{Characters: single, Data: blocks}
  150. }
  151. func ExtractBlock(name string, offsets []uint16, data []byte) (Font door.BlockFont) {
  152. defer func() {
  153. if r := recover(); r != nil {
  154. // Ok, this failed
  155. Font = door.BlockFont{}
  156. }
  157. }()
  158. // fmt.Printf("Extract Block Font: %s\n", name)
  159. var indexes []int
  160. var blocks [][][]byte
  161. var current [][]byte
  162. var line []byte
  163. pos := 0
  164. for pos < len(data) {
  165. indexes = append(indexes, pos)
  166. current = make([][]byte, 0)
  167. line = make([]byte, 0)
  168. // We don't use these
  169. // w = data[pos]
  170. // h = data[pos+1]
  171. pos += 2
  172. // process this character
  173. for pos < len(data) {
  174. ch := data[pos]
  175. pos++
  176. if ch == 0x00 {
  177. // end of character
  178. current = append(current, line)
  179. blocks = append(blocks, current)
  180. // current = make([][]byte, 0)
  181. // line = make([]byte, 0)
  182. break
  183. }
  184. if ch == 0x0d {
  185. // end of this character line
  186. current = append(current, line)
  187. line = make([]byte, 0)
  188. continue
  189. }
  190. if ch == 0x26 {
  191. // & descender mark
  192. continue
  193. }
  194. line = append(line, ch)
  195. }
  196. }
  197. // offset optimization:
  198. var single []int
  199. for _, o := range offsets {
  200. if o == 65535 {
  201. single = append(single, -1)
  202. continue
  203. }
  204. found := false
  205. for idx, i := range indexes {
  206. if o == uint16(i) {
  207. single = append(single, idx)
  208. found = true
  209. break
  210. }
  211. }
  212. if !found {
  213. panic(fmt.Sprintf("Unable to locate index %d / %x (font appears corrupted)", o, o))
  214. }
  215. }
  216. return door.BlockFont{Characters: single, Data: blocks}
  217. }