bitmap.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright ©2021 The star-tex Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE-STAR-TEX file.
  4. package pkf
  5. import (
  6. "fmt"
  7. "io"
  8. )
  9. // Bitmap displays the rune c as an ASCII bitmap to the provided writer.
  10. func (fnt *Font) Bitmap(o io.Writer, c rune, h, w int) error {
  11. const raw = false
  12. return fnt.displayGlyph(o, c, h, w, raw, func(w io.Writer, u uint8, n int) {
  13. bit := uint8(1 << 7)
  14. for ; n > 0; n-- {
  15. switch {
  16. case u&bit != 0:
  17. fmt.Fprintf(w, "*")
  18. default:
  19. fmt.Fprintf(w, ".")
  20. }
  21. bit >>= 1
  22. }
  23. })
  24. }
  25. // Hexmap displays the rune c as an ASCII hexmap to the provided writer.
  26. func (fnt *Font) Hexmap(o io.Writer, c rune, h, w int) error {
  27. const raw = false
  28. return fnt.displayGlyph(o, c, h, w, raw, func(w io.Writer, v uint8, n int) {
  29. fmt.Fprintf(w, "%02x", v)
  30. })
  31. }
  32. // Rawmap displays the rune c as an ASCII rawmap to the provided writer.
  33. func (fnt *Font) Rawmap(o io.Writer, c rune, h, w int) error {
  34. const raw = true
  35. return fnt.displayGlyph(o, c, h, w, raw, func(w io.Writer, v uint8, n int) {
  36. fmt.Fprintf(w, "0x%02x, ", lsbf(v))
  37. })
  38. }
  39. func (fnt *Font) displayGlyph(o io.Writer, c rune, h, w int, raw bool, fun func(w io.Writer, u uint8, n int)) error {
  40. var g *Glyph
  41. for i := range fnt.glyphs {
  42. if fnt.glyphs[i].code == uint32(c) {
  43. g = &fnt.glyphs[i]
  44. g.unpack()
  45. break
  46. }
  47. }
  48. if g == nil {
  49. return fmt.Errorf("could not find glyph 0x%x", c)
  50. }
  51. var (
  52. H, dh int
  53. W, dw int
  54. )
  55. H = int(g.height)
  56. if h == 0 {
  57. h = H
  58. }
  59. dh = (h - H) / 2
  60. W = int(g.width)
  61. if w == 0 {
  62. w = W
  63. }
  64. dw = (w - W) / 2
  65. fmt.Fprintf(o, "\n")
  66. switch {
  67. case raw:
  68. fmt.Fprintf(o, "#define %s_%c_width \t %d\n", "fname", g.code, w)
  69. fmt.Fprintf(o, "#define %s_%c_height \t %d\n", "fname", g.code, h)
  70. fmt.Fprintf(o, "#define %s_%c_xoff \t %d\n", "fname", g.code, dw)
  71. fmt.Fprintf(o, "#define %s_%c_yoff \t %d\n", "fname", g.code, dh)
  72. fmt.Fprintf(o, "static char %s_%c_bits[] = {", "fname", g.code)
  73. default:
  74. fmt.Fprintf(o, "character : %d (%c)\n", g.code, g.code)
  75. fmt.Fprintf(o, " height : %d\n", g.height)
  76. fmt.Fprintf(o, " width : %d\n", g.width)
  77. fmt.Fprintf(o, " xoff : %d\n", g.xoff)
  78. fmt.Fprintf(o, " yoff : %d\n", g.yoff)
  79. }
  80. for row := 0; row < h-H-dh; row++ {
  81. fmt.Fprintf(o, "\n ")
  82. for col := 0; col < w; col += 8 {
  83. n := clip(w-col, 8)
  84. fun(o, 0, n)
  85. }
  86. }
  87. var i int
  88. for row := 0; row < int(g.height); row++ {
  89. fmt.Fprintf(o, "\n ")
  90. for col := 0; col < int(g.width); col += 8 {
  91. v := g.mask[i]
  92. n := clip(int(g.width)-col, 8)
  93. fun(o, v, n)
  94. i++
  95. }
  96. }
  97. for row := h - dh; row < h; row++ {
  98. fmt.Fprintf(o, "\n ")
  99. for col := 0; col < w; col += 8 {
  100. n := clip(w-col, 8)
  101. fun(o, 0, n)
  102. }
  103. }
  104. switch {
  105. case raw:
  106. fmt.Fprintf(o, "};\n")
  107. default:
  108. fmt.Fprintf(o, "\n")
  109. }
  110. return nil
  111. }
  112. func clip(v, max int) int {
  113. if v >= max {
  114. return max
  115. }
  116. return v
  117. }
  118. func lsbf(u uint8) uint8 {
  119. var (
  120. bit, o uint8
  121. )
  122. for i := 0; i < 8; i++ {
  123. bit = u & 0o1
  124. o = (o << 1) | bit
  125. u = u >> 1
  126. }
  127. return o
  128. }