utils.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 true {
  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. func text_to_hextext(line string) string {
  68. var output string
  69. // output = "\""
  70. for _, ch := range []byte(line) {
  71. // output += fmt.Sprintf("\\x%02x", ch)
  72. output += fmt.Sprintf("0x%02x,", ch)
  73. }
  74. if len(output) > 1 {
  75. output = output[:len(output)-1]
  76. }
  77. // output += "\""
  78. return output
  79. }
  80. func ExtractColor(name string, offsets []uint16, data []byte) (Font door.ColorFont) {
  81. defer func() {
  82. if r := recover(); r != nil {
  83. // Ok, this failed
  84. Font = door.ColorFont{}
  85. }
  86. }()
  87. var indexes []int
  88. var blocks [][][]byte
  89. var current [][]byte
  90. var line []byte
  91. pos := 0
  92. for pos < len(data) {
  93. indexes = append(indexes, pos)
  94. current = make([][]byte, 0)
  95. line = make([]byte, 0)
  96. // We don't use these.
  97. // w = data[pos]
  98. // h = data[pos+1]
  99. pos += 2
  100. // process this character
  101. for pos < len(data) {
  102. ch := data[pos]
  103. pos++
  104. if ch == 0x00 {
  105. // end of character
  106. current = append(current, line)
  107. blocks = append(blocks, current)
  108. current = make([][]byte, 0)
  109. line = make([]byte, 0)
  110. break
  111. }
  112. if ch == 0x0d {
  113. // end of this character line
  114. current = append(current, line)
  115. line = make([]byte, 0)
  116. continue
  117. }
  118. if ch == 0x26 {
  119. // & descender mark
  120. continue
  121. }
  122. line = append(line, ch)
  123. color := data[pos]
  124. pos++
  125. line = append(line, color)
  126. }
  127. }
  128. // offset optimization:
  129. var single []int
  130. for _, o := range offsets {
  131. if o == 65535 {
  132. single = append(single, -1)
  133. continue
  134. }
  135. found := false
  136. for idx, i := range indexes {
  137. if o == uint16(i) {
  138. single = append(single, idx)
  139. found = true
  140. break
  141. }
  142. }
  143. if !found {
  144. panic(fmt.Sprintf("Unable to locate index %d / %x (font appears corrupted)", o, o))
  145. }
  146. }
  147. return door.ColorFont{Characters: single, Data: blocks}
  148. }
  149. func ExtractBlock(name string, offsets []uint16, data []byte) (Font door.BlockFont) {
  150. defer func() {
  151. if r := recover(); r != nil {
  152. // Ok, this failed
  153. Font = door.BlockFont{}
  154. }
  155. }()
  156. // fmt.Printf("Extract Block Font: %s\n", name)
  157. var indexes []int
  158. var blocks [][][]byte
  159. var current [][]byte
  160. var line []byte
  161. pos := 0
  162. for pos < len(data) {
  163. indexes = append(indexes, pos)
  164. current = make([][]byte, 0)
  165. line = make([]byte, 0)
  166. // We don't use these
  167. // w = data[pos]
  168. // h = data[pos+1]
  169. pos += 2
  170. // process this character
  171. for pos < len(data) {
  172. ch := data[pos]
  173. pos++
  174. if ch == 0x00 {
  175. // end of character
  176. current = append(current, line)
  177. blocks = append(blocks, current)
  178. current = make([][]byte, 0)
  179. line = make([]byte, 0)
  180. break
  181. }
  182. if ch == 0x0d {
  183. // end of this character line
  184. current = append(current, line)
  185. line = make([]byte, 0)
  186. continue
  187. }
  188. if ch == 0x26 {
  189. // & descender mark
  190. continue
  191. }
  192. line = append(line, ch)
  193. }
  194. }
  195. // offset optimization:
  196. var single []int
  197. for _, o := range offsets {
  198. if o == 65535 {
  199. single = append(single, -1)
  200. continue
  201. }
  202. found := false
  203. for idx, i := range indexes {
  204. if o == uint16(i) {
  205. single = append(single, idx)
  206. found = true
  207. break
  208. }
  209. }
  210. if !found {
  211. panic(fmt.Sprintf("Unable to locate index %d / %x (font appears corrupted)", o, o))
  212. }
  213. }
  214. return door.BlockFont{Characters: single, Data: blocks}
  215. }