index.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. module.exports = function parseBMFontAscii(data) {
  2. if (!data)
  3. throw new Error('no data provided')
  4. data = data.toString().trim()
  5. var output = {
  6. pages: [],
  7. chars: [],
  8. kernings: []
  9. }
  10. var lines = data.split(/\r\n?|\n/g)
  11. if (lines.length === 0)
  12. throw new Error('no data in BMFont file')
  13. for (var i = 0; i < lines.length; i++) {
  14. var lineData = splitLine(lines[i], i)
  15. if (!lineData) //skip empty lines
  16. continue
  17. if (lineData.key === 'page') {
  18. if (typeof lineData.data.id !== 'number')
  19. throw new Error('malformed file at line ' + i + ' -- needs page id=N')
  20. if (typeof lineData.data.file !== 'string')
  21. throw new Error('malformed file at line ' + i + ' -- needs page file="path"')
  22. output.pages[lineData.data.id] = lineData.data.file
  23. } else if (lineData.key === 'chars' || lineData.key === 'kernings') {
  24. //... do nothing for these two ...
  25. } else if (lineData.key === 'char') {
  26. output.chars.push(lineData.data)
  27. } else if (lineData.key === 'kerning') {
  28. output.kernings.push(lineData.data)
  29. } else {
  30. output[lineData.key] = lineData.data
  31. }
  32. }
  33. return output
  34. }
  35. function splitLine(line, idx) {
  36. line = line.replace(/\t+/g, ' ').trim()
  37. if (!line)
  38. return null
  39. var space = line.indexOf(' ')
  40. if (space === -1)
  41. throw new Error("no named row at line " + idx)
  42. var key = line.substring(0, space)
  43. line = line.substring(space + 1)
  44. //clear "letter" field as it is non-standard and
  45. //requires additional complexity to parse " / = symbols
  46. line = line.replace(/letter=[\'\"]\S+[\'\"]/gi, '')
  47. line = line.split("=")
  48. line = line.map(function(str) {
  49. return str.trim().match((/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g))
  50. })
  51. var data = []
  52. for (var i = 0; i < line.length; i++) {
  53. var dt = line[i]
  54. if (i === 0) {
  55. data.push({
  56. key: dt[0],
  57. data: ""
  58. })
  59. } else if (i === line.length - 1) {
  60. data[data.length - 1].data = parseData(dt[0])
  61. } else {
  62. data[data.length - 1].data = parseData(dt[0])
  63. data.push({
  64. key: dt[1],
  65. data: ""
  66. })
  67. }
  68. }
  69. var out = {
  70. key: key,
  71. data: {}
  72. }
  73. data.forEach(function(v) {
  74. out.data[v.key] = v.data;
  75. })
  76. return out
  77. }
  78. function parseData(data) {
  79. if (!data || data.length === 0)
  80. return ""
  81. if (data.indexOf('"') === 0 || data.indexOf("'") === 0)
  82. return data.substring(1, data.length - 1)
  83. if (data.indexOf(',') !== -1)
  84. return parseIntList(data)
  85. return parseInt(data, 10)
  86. }
  87. function parseIntList(data) {
  88. return data.split(',').map(function(val) {
  89. return parseInt(val, 10)
  90. })
  91. }