You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.6 KiB
108 lines
2.6 KiB
module.exports = function parseBMFontAscii(data) { |
|
if (!data) |
|
throw new Error('no data provided') |
|
data = data.toString().trim() |
|
|
|
var output = { |
|
pages: [], |
|
chars: [], |
|
kernings: [] |
|
} |
|
|
|
var lines = data.split(/\r\n?|\n/g) |
|
|
|
if (lines.length === 0) |
|
throw new Error('no data in BMFont file') |
|
|
|
for (var i = 0; i < lines.length; i++) { |
|
var lineData = splitLine(lines[i], i) |
|
if (!lineData) //skip empty lines |
|
continue |
|
|
|
if (lineData.key === 'page') { |
|
if (typeof lineData.data.id !== 'number') |
|
throw new Error('malformed file at line ' + i + ' -- needs page id=N') |
|
if (typeof lineData.data.file !== 'string') |
|
throw new Error('malformed file at line ' + i + ' -- needs page file="path"') |
|
output.pages[lineData.data.id] = lineData.data.file |
|
} else if (lineData.key === 'chars' || lineData.key === 'kernings') { |
|
//... do nothing for these two ... |
|
} else if (lineData.key === 'char') { |
|
output.chars.push(lineData.data) |
|
} else if (lineData.key === 'kerning') { |
|
output.kernings.push(lineData.data) |
|
} else { |
|
output[lineData.key] = lineData.data |
|
} |
|
} |
|
|
|
return output |
|
} |
|
|
|
function splitLine(line, idx) { |
|
line = line.replace(/\t+/g, ' ').trim() |
|
if (!line) |
|
return null |
|
|
|
var space = line.indexOf(' ') |
|
if (space === -1) |
|
throw new Error("no named row at line " + idx) |
|
|
|
var key = line.substring(0, space) |
|
|
|
line = line.substring(space + 1) |
|
//clear "letter" field as it is non-standard and |
|
//requires additional complexity to parse " / = symbols |
|
line = line.replace(/letter=[\'\"]\S+[\'\"]/gi, '') |
|
line = line.split("=") |
|
line = line.map(function(str) { |
|
return str.trim().match((/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g)) |
|
}) |
|
|
|
var data = [] |
|
for (var i = 0; i < line.length; i++) { |
|
var dt = line[i] |
|
if (i === 0) { |
|
data.push({ |
|
key: dt[0], |
|
data: "" |
|
}) |
|
} else if (i === line.length - 1) { |
|
data[data.length - 1].data = parseData(dt[0]) |
|
} else { |
|
data[data.length - 1].data = parseData(dt[0]) |
|
data.push({ |
|
key: dt[1], |
|
data: "" |
|
}) |
|
} |
|
} |
|
|
|
var out = { |
|
key: key, |
|
data: {} |
|
} |
|
|
|
data.forEach(function(v) { |
|
out.data[v.key] = v.data; |
|
}) |
|
|
|
return out |
|
} |
|
|
|
function parseData(data) { |
|
if (!data || data.length === 0) |
|
return "" |
|
|
|
if (data.indexOf('"') === 0 || data.indexOf("'") === 0) |
|
return data.substring(1, data.length - 1) |
|
if (data.indexOf(',') !== -1) |
|
return parseIntList(data) |
|
return parseInt(data, 10) |
|
} |
|
|
|
function parseIntList(data) { |
|
return data.split(',').map(function(val) { |
|
return parseInt(val, 10) |
|
}) |
|
} |