fnl.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "strings"
  6. )
  7. // FNL represents the header of the fnl1 section
  8. type FNL struct {
  9. NumOfFonts uint16
  10. _ uint16
  11. }
  12. type FNLTable struct {
  13. // OffSet is relative to the beginning of the fnl1 section
  14. Offset uint32
  15. _ uint32
  16. }
  17. func (r *Root) ParseFNL(data []byte, sectionSize uint32) {
  18. var fontOffsets []uint32
  19. var fontNames []string
  20. var fnl FNL
  21. err := binary.Read(bytes.NewReader(data), binary.BigEndian, &fnl)
  22. if err != nil {
  23. panic(err)
  24. }
  25. for i := 0; i < int(fnl.NumOfFonts); i++ {
  26. // By now we have only read the header.
  27. // We will read the FNLOffset table in order to get our names.
  28. var fnlTable FNLTable
  29. offset := 4 + (i * 8)
  30. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &fnlTable)
  31. if err != nil {
  32. panic(err)
  33. }
  34. fontOffsets = append(fontOffsets, fnlTable.Offset+4)
  35. // If we have reached the last index, append the section size to the slice.
  36. if i == int(fnl.NumOfFonts)-1 {
  37. fontOffsets = append(fontOffsets, sectionSize-8)
  38. }
  39. }
  40. // Now that we have the offsets, retrieve the TPL names.
  41. for i := 0; i < int(fnl.NumOfFonts); i++ {
  42. fontName := string(data[fontOffsets[i]:fontOffsets[i+1]])
  43. // Strip the null terminator
  44. fontName = strings.Replace(fontName, "\x00", "", -1)
  45. fontNames = append(fontNames, fontName)
  46. }
  47. r.FNL = &FNLNames{FNLName: fontNames}
  48. }
  49. func (b *BRLYTWriter) WriteFNL(data Root) {
  50. // TODO: Write the number of fonts instead of 1. I have observed that there is only 1 fnl section so I am writing only 1.
  51. temp := bytes.NewBuffer(nil)
  52. header := SectionHeader{
  53. Type: SectionTypeFNL,
  54. Size: uint32(21 + len(data.FNL.FNLName[0])),
  55. }
  56. meta := FNL{NumOfFonts: 1}
  57. table := FNLTable{Offset: 8}
  58. write(temp, header)
  59. write(temp, meta)
  60. write(temp, table)
  61. _, err := temp.WriteString(data.FNL.FNLName[0])
  62. if err != nil {
  63. panic(err)
  64. }
  65. // Write null terminator
  66. temp.WriteByte(0)
  67. for (b.Len()+temp.Len())%4 != 0 {
  68. temp.WriteByte(0)
  69. }
  70. binary.BigEndian.PutUint32(temp.Bytes()[4:8], uint32(temp.Len()))
  71. write(b, temp.Bytes())
  72. }