tfm.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 tfm implements a decoder for TFM (TeX Font Metrics) files.
  5. package tfm // import "modernc.org/knuth/font/tfm"
  6. import (
  7. "fmt"
  8. )
  9. type glyphKind uint8
  10. const (
  11. gkInvalid glyphKind = iota
  12. gkVanilla
  13. gkLigKern
  14. gkGlyphList
  15. gkExtensible
  16. )
  17. func (ck glyphKind) String() string {
  18. switch ck {
  19. case gkVanilla:
  20. return "vanilla"
  21. case gkLigKern:
  22. return "ligkern"
  23. case gkGlyphList:
  24. return "glyphlist"
  25. case gkExtensible:
  26. return "extglyph"
  27. case gkInvalid:
  28. return "invalid"
  29. default:
  30. return fmt.Sprintf("glyphKind(%d)", int(ck))
  31. }
  32. }
  33. // glyphIndex is a glyph index in a Font.
  34. type glyphIndex int
  35. // glyphInfo provides informations about a glyph.
  36. type glyphInfo struct {
  37. raw [4]uint8
  38. }
  39. func (g glyphInfo) wd() int {
  40. return int(g.raw[0])
  41. }
  42. func (g glyphInfo) ht() int {
  43. return int((g.raw[1] & 0b1111_0000) >> 4)
  44. }
  45. func (g glyphInfo) dp() int {
  46. return int(g.raw[1] & 0b0000_1111)
  47. }
  48. func (g glyphInfo) ic() int {
  49. return int((g.raw[2] & 0b1111_1100) >> 2)
  50. }
  51. func (g glyphInfo) kind() (glyphKind, int) {
  52. i := int(g.raw[3])
  53. switch g.raw[2] & 0b0000_0011 {
  54. case 0:
  55. return gkVanilla, i
  56. case 1:
  57. return gkLigKern, i
  58. case 2:
  59. return gkGlyphList, i
  60. case 3:
  61. return gkExtensible, i
  62. default:
  63. return gkInvalid, -i
  64. }
  65. }
  66. type ligKernCmd struct {
  67. raw [4]uint8
  68. }
  69. func (lk ligKernCmd) skipByte() bool {
  70. return lk.raw[0] > 128
  71. }
  72. func (lk ligKernCmd) nextChar() int {
  73. return int(lk.raw[1])
  74. }
  75. func (lk ligKernCmd) op() ligKernOp {
  76. if lk.raw[2] < 128 {
  77. return ligCmd
  78. }
  79. return krnCmd
  80. }
  81. func (lk ligKernCmd) nextIndex() int {
  82. return (int(lk.raw[2])-128)*256 + int(lk.raw[3])
  83. }
  84. type ligKernOp uint8
  85. const (
  86. lkUknown ligKernOp = iota
  87. ligCmd
  88. krnCmd
  89. )
  90. func (lk ligKernOp) String() string {
  91. switch lk {
  92. default:
  93. return "invalid"
  94. case ligCmd:
  95. return "LIG"
  96. case krnCmd:
  97. return "KRN"
  98. }
  99. }
  100. type extensible struct {
  101. raw [4]uint8
  102. }