glyph.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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. "image"
  8. "modernc.org/knuth/internal/iobuf"
  9. )
  10. // Glyph represents a glyph contained in a PK font file.
  11. type Glyph struct {
  12. flag uint8
  13. code uint32 // character code
  14. wtfm uint32 // TFM width
  15. dx uint32 // horizontal escapement
  16. dy uint32 // vertical escapement
  17. width uint32 // width in pixels of the minimum bounding box
  18. height uint32 // height in pixels of the minimum bounding box
  19. xoff int32 // horizontal offset from the upper left pixel
  20. yoff int32 // vertical offset from the upper left pixel
  21. data []byte
  22. mask []byte
  23. }
  24. func (g *Glyph) unpack() {
  25. if g.mask != nil {
  26. return
  27. }
  28. gr := glyphReader{
  29. r: iobuf.NewReader(g.data),
  30. g: g,
  31. }
  32. g.mask = gr.unpack()
  33. }
  34. func (g *Glyph) Mask() image.Alpha {
  35. g.unpack()
  36. h := int(g.height)
  37. w := int(g.width)
  38. pix := make([]byte, 0, h*w)
  39. var i int
  40. for row := 0; row < h; row++ {
  41. for col := 0; col < w; col += 8 {
  42. v := g.mask[i]
  43. n := clip(w-col, 8)
  44. bit := uint8(1 << 7)
  45. for ; n > 0; n-- {
  46. switch {
  47. case v&bit != 0:
  48. pix = append(pix, 0xff)
  49. default:
  50. pix = append(pix, 0x00)
  51. }
  52. bit >>= 1
  53. }
  54. i++
  55. }
  56. }
  57. return image.Alpha{
  58. Stride: w,
  59. Pix: pix,
  60. Rect: image.Rect(0, 0, w, h),
  61. }
  62. }
  63. func (g *Glyph) Bounds() image.Rectangle {
  64. h := int(g.height)
  65. w := int(g.width)
  66. return image.Rect(0, 0, w, h)
  67. }
  68. func readGlyph(r *iobuf.Reader) (g Glyph, err error) {
  69. var (
  70. pos = r.Pos()
  71. raster uint32
  72. )
  73. g.flag = r.ReadU8()
  74. switch g.flag & 7 {
  75. case 0, 1, 2, 3:
  76. // 'short' character description.
  77. // flag[1] pl[1] cc[1] tfm[3] dm[1] w[1] h[1] hoff[+1] voff[+1]
  78. raster = uint32(g.flag&7)*(2<<7) + uint32(r.ReadU8()) - 4
  79. g.code = uint32(r.ReadU8())
  80. g.wtfm = r.ReadU24()
  81. g.dx = uint32(r.ReadU8()) * 65536
  82. g.dy = 0
  83. g.width = uint32(r.ReadU8())
  84. g.height = uint32(r.ReadU8())
  85. g.xoff = int32(r.ReadI8())
  86. g.yoff = int32(r.ReadI8())
  87. raster -= 4
  88. case 4, 5, 6:
  89. // 'extended short' character description.
  90. // flag[1] pl[2] cc[1] tfm[3] dm[2] w[2] h[2] hoff[+2] voff[+2].
  91. raster = uint32(g.flag&3)*(2<<15) + uint32(r.ReadU16()) - 5
  92. g.code = uint32(r.ReadU8())
  93. g.wtfm = r.ReadU24()
  94. g.dx = uint32(r.ReadU16()) * 65536
  95. g.dy = 0
  96. g.width = uint32(r.ReadU16())
  97. g.height = uint32(r.ReadU16())
  98. g.xoff = int32(r.ReadI16())
  99. g.yoff = int32(r.ReadI16())
  100. raster -= 4 * 2
  101. case 7:
  102. // 'long' character description.
  103. // flag[1] pl[4] cc[4] tfm[4] dx[4] dy[4] w[4] h[4] hoff[4] voff[4]
  104. raster = r.ReadU32() - 12
  105. g.code = r.ReadU32()
  106. g.wtfm = r.ReadU32()
  107. g.dx = r.ReadU32()
  108. g.dy = r.ReadU32()
  109. g.width = r.ReadU32()
  110. g.height = r.ReadU32()
  111. g.xoff = int32(r.ReadU32())
  112. g.yoff = int32(r.ReadU32())
  113. raster -= 4 * 4
  114. }
  115. g.data = r.ReadBuf(int(raster))
  116. g.mask = nil
  117. if false {
  118. dynf := g.flag / 16
  119. fmt.Printf(
  120. "%d: Flag byte = %d Character = %d Packet length = %d\n"+
  121. " Dynamic packing variable = %d\n"+
  122. " TFM width = %d dx = %d%s\n"+
  123. " Height = %d Width = %d X-offset = %d Y-offset = %d\n",
  124. pos, g.flag, g.code, raster,
  125. dynf,
  126. g.wtfm, g.dx, func() string {
  127. switch g.dy {
  128. case 0:
  129. return " "
  130. default:
  131. return fmt.Sprintf(" dy = %d", g.dy)
  132. }
  133. }(),
  134. g.height, g.width, g.xoff, g.yoff,
  135. )
  136. }
  137. return g, err
  138. }
  139. type glyphReader struct {
  140. r *iobuf.Reader
  141. g *Glyph
  142. inputbyte uint16
  143. bitweight uint16
  144. dynf uint32
  145. repeat uint32
  146. remainder int32
  147. read func() uint32
  148. }
  149. func (gr *glyphReader) init() {
  150. gr.r.SetPos(0)
  151. gr.repeat = 0
  152. gr.inputbyte = 0
  153. gr.bitweight = 0
  154. gr.dynf = uint32(gr.g.flag / 16)
  155. gr.read = gr.pknum
  156. }
  157. var gpower = [17]uint16{
  158. 0, 1, 3, 7, 15, 31, 63, 127,
  159. 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535,
  160. }
  161. func (gr *glyphReader) unpack() []byte {
  162. var (
  163. wordwidth = int16((gr.g.width + 15) / 16)
  164. word uint16
  165. wordweight uint16
  166. rowsleft int16
  167. turnon = gr.g.flag&8 != 0
  168. hbit int16
  169. count uint16
  170. mask []uint8
  171. )
  172. gr.init()
  173. sz := 2 * gr.g.height * uint32(wordwidth)
  174. if sz <= 0 {
  175. sz = 2
  176. }
  177. var (
  178. idx int
  179. sli = make([]uint16, sz/2+1) // divide by 2: sz is in bytes
  180. raster = sli[1:]
  181. )
  182. switch gr.dynf {
  183. case 14:
  184. gr.bitweight = 0
  185. for i := 0; i < int(gr.g.height); i++ {
  186. word = 0
  187. wordweight = 32768
  188. for j := 0; j < int(gr.g.width); j++ {
  189. if gr.getbit() {
  190. word += wordweight
  191. }
  192. wordweight >>= 1
  193. if wordweight == 0 {
  194. raster[idx] = word
  195. idx++
  196. word = 0
  197. wordweight = 32768
  198. }
  199. }
  200. if wordweight != 32768 {
  201. raster[idx] = word
  202. idx++
  203. }
  204. }
  205. default:
  206. rowsleft = int16(gr.g.height)
  207. hbit = int16(gr.g.width)
  208. wordweight = 16
  209. word = 0
  210. for rowsleft > 0 {
  211. count = uint16(gr.read())
  212. for count != 0 {
  213. switch {
  214. case count < wordweight && count < uint16(hbit):
  215. if turnon {
  216. word += gpower[wordweight] - gpower[wordweight-count]
  217. }
  218. hbit -= int16(count)
  219. wordweight -= count
  220. count = 0
  221. case count >= uint16(hbit) && uint16(hbit) <= wordweight:
  222. if turnon {
  223. word += gpower[wordweight] - gpower[wordweight-uint16(hbit)]
  224. }
  225. raster[idx] = word
  226. idx++
  227. for i := 0; i < int(gr.repeat); i++ {
  228. for j := 0; j < int(wordwidth); j++ {
  229. raster[idx] = raster[idx-int(wordwidth)]
  230. idx++
  231. }
  232. }
  233. rowsleft -= int16(gr.repeat) + 1
  234. gr.repeat = 0
  235. word = 0
  236. wordweight = 16
  237. count -= uint16(hbit)
  238. hbit = int16(gr.g.width)
  239. default:
  240. if turnon {
  241. word += gpower[wordweight]
  242. }
  243. raster[idx] = word
  244. idx++
  245. word = 0
  246. count -= wordweight
  247. hbit -= int16(wordweight)
  248. wordweight = 16
  249. }
  250. }
  251. turnon = !turnon
  252. }
  253. if rowsleft != 0 || hbit != int16(gr.g.width) {
  254. panic(fmt.Errorf("error while unpacking: more bits than required: rowsleft=%d hbit=%d width=%d",
  255. rowsleft, hbit, gr.g.width,
  256. ))
  257. }
  258. }
  259. {
  260. // build raster data
  261. var (
  262. widx = 0
  263. word = sli
  264. )
  265. for row := 0; row < int(gr.g.height); row++ {
  266. var (
  267. bitsleft uint8
  268. nextword uint16
  269. nextbyte uint8
  270. )
  271. for col := 0; col < int(gr.g.width); col += 8 {
  272. switch {
  273. case bitsleft >= 8:
  274. nextbyte = uint8(nextword >> (bitsleft - 8) & 0xff)
  275. bitsleft -= 8
  276. mask = append(mask, nextbyte)
  277. default:
  278. nextbyte = uint8(nextword << (8 - bitsleft) & 0xff)
  279. widx++
  280. nextword = word[widx]
  281. nextbyte = nextbyte | uint8(nextword>>(16-(8-bitsleft))&0xff)
  282. bitsleft = 16 - (8 - bitsleft)
  283. mask = append(mask, nextbyte)
  284. }
  285. }
  286. }
  287. }
  288. return mask
  289. }
  290. func (gr *glyphReader) pkbyte() uint16 {
  291. return uint16(gr.r.ReadU8())
  292. }
  293. func (gr *glyphReader) pknum() uint32 {
  294. var (
  295. i, j uint16
  296. dynf = uint16(gr.dynf)
  297. )
  298. i = uint16(gr.nyb())
  299. switch {
  300. case i == 0:
  301. for {
  302. j = uint16(gr.nyb())
  303. i++
  304. if j != 0 {
  305. break
  306. }
  307. }
  308. switch {
  309. case i > 3:
  310. return gr.huge(i, j)
  311. default:
  312. for i > 0 {
  313. j = j*16 + uint16(gr.nyb())
  314. i--
  315. }
  316. return uint32(j - 15 + (13-dynf)*16 + dynf)
  317. }
  318. case i <= dynf:
  319. return uint32(i)
  320. case i < 14:
  321. v := dynf + 1
  322. return uint32((i-v)*16 + uint16(gr.nyb()) + v)
  323. default:
  324. switch i {
  325. case 14:
  326. gr.repeat = gr.pknum()
  327. default:
  328. gr.repeat = 1
  329. }
  330. return gr.read()
  331. }
  332. }
  333. func (gr *glyphReader) rest() uint32 {
  334. switch {
  335. case gr.remainder < 0:
  336. gr.remainder = -gr.remainder
  337. return 0
  338. case gr.remainder > 0:
  339. switch {
  340. case gr.remainder > 4000:
  341. gr.remainder = 4000 - gr.remainder
  342. return 4000
  343. default:
  344. i := uint32(gr.remainder)
  345. gr.remainder = 0
  346. gr.read = gr.pknum
  347. return i
  348. }
  349. }
  350. panic("impossible")
  351. }
  352. func (gr *glyphReader) huge(i, k uint16) uint32 {
  353. var (
  354. j = k
  355. dynf = int32(gr.dynf)
  356. )
  357. for i != 0 {
  358. j = (j << 4) + uint16(gr.nyb())
  359. i--
  360. }
  361. gr.remainder = int32(j) - 15 + (13-dynf)*16 + dynf
  362. gr.read = gr.rest
  363. return gr.rest()
  364. }
  365. func (gr *glyphReader) nyb() int16 {
  366. var v uint16
  367. switch gr.bitweight {
  368. case 0:
  369. gr.bitweight = 16
  370. gr.inputbyte = gr.pkbyte()
  371. v = gr.inputbyte >> 4
  372. default:
  373. gr.bitweight = 0
  374. v = gr.inputbyte & 15
  375. }
  376. return int16(v)
  377. }
  378. func (gr *glyphReader) getbit() bool {
  379. gr.bitweight >>= 1
  380. if gr.bitweight == 0 {
  381. gr.inputbyte = gr.pkbyte()
  382. gr.bitweight = 128
  383. }
  384. return gr.inputbyte&gr.bitweight != 0
  385. }