diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 96d9f44..b505250 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -503,10 +503,10 @@
*
* @static
* @param {XMLDocument} xml - The XML document data.
- * @param {PIXI.Texture} texture - Texture with all symbols.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
* @return {Object} Result font object with font, size, lineHeight and char fields.
*/
- static registerFont(xml, texture)
+ static registerFont(xml, textures)
{
const data = {};
const info = xml.getElementsByTagName('info')[0];
@@ -518,29 +518,44 @@
data.size = parseInt(info.getAttribute('size'), 10);
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res;
data.chars = {};
+ if (!(textures instanceof Array))
+ {
+ textures = [textures];
+ }
// parse letters
const letters = xml.getElementsByTagName('char');
+ let page;
for (let i = 0; i < letters.length; i++)
{
const letter = letters[i];
const charCode = parseInt(letter.getAttribute('id'), 10);
+ let textureRect;
- const textureRect = new core.Rectangle(
- (parseInt(letter.getAttribute('x'), 10) / res) + (texture.frame.x / res),
- (parseInt(letter.getAttribute('y'), 10) / res) + (texture.frame.y / res),
- parseInt(letter.getAttribute('width'), 10) / res,
- parseInt(letter.getAttribute('height'), 10) / res
- );
+ page = parseInt(letter.getAttribute('page'), 10);
+ if (isNaN(page))
+ {
+ textureRect = new core.Rectangle(0, 0, 0, 0);
+ page = 0;
+ }
+ else
+ {
+ textureRect = new core.Rectangle(
+ (parseInt(letter.getAttribute('x'), 10) / res) + (textures[page].frame.x / res),
+ (parseInt(letter.getAttribute('y'), 10) / res) + (textures[page].frame.y / res),
+ parseInt(letter.getAttribute('width'), 10) / res,
+ parseInt(letter.getAttribute('height'), 10) / res
+ );
+ }
data.chars[charCode] = {
xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res,
yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res,
xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res,
kerning: {},
- texture: new core.Texture(texture.baseTexture, textureRect),
-
+ texture: new core.Texture(textures[page].baseTexture, textureRect),
+ page,
};
}
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 96d9f44..b505250 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -503,10 +503,10 @@
*
* @static
* @param {XMLDocument} xml - The XML document data.
- * @param {PIXI.Texture} texture - Texture with all symbols.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
* @return {Object} Result font object with font, size, lineHeight and char fields.
*/
- static registerFont(xml, texture)
+ static registerFont(xml, textures)
{
const data = {};
const info = xml.getElementsByTagName('info')[0];
@@ -518,29 +518,44 @@
data.size = parseInt(info.getAttribute('size'), 10);
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res;
data.chars = {};
+ if (!(textures instanceof Array))
+ {
+ textures = [textures];
+ }
// parse letters
const letters = xml.getElementsByTagName('char');
+ let page;
for (let i = 0; i < letters.length; i++)
{
const letter = letters[i];
const charCode = parseInt(letter.getAttribute('id'), 10);
+ let textureRect;
- const textureRect = new core.Rectangle(
- (parseInt(letter.getAttribute('x'), 10) / res) + (texture.frame.x / res),
- (parseInt(letter.getAttribute('y'), 10) / res) + (texture.frame.y / res),
- parseInt(letter.getAttribute('width'), 10) / res,
- parseInt(letter.getAttribute('height'), 10) / res
- );
+ page = parseInt(letter.getAttribute('page'), 10);
+ if (isNaN(page))
+ {
+ textureRect = new core.Rectangle(0, 0, 0, 0);
+ page = 0;
+ }
+ else
+ {
+ textureRect = new core.Rectangle(
+ (parseInt(letter.getAttribute('x'), 10) / res) + (textures[page].frame.x / res),
+ (parseInt(letter.getAttribute('y'), 10) / res) + (textures[page].frame.y / res),
+ parseInt(letter.getAttribute('width'), 10) / res,
+ parseInt(letter.getAttribute('height'), 10) / res
+ );
+ }
data.chars[charCode] = {
xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res,
yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res,
xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res,
kerning: {},
- texture: new core.Texture(texture.baseTexture, textureRect),
-
+ texture: new core.Texture(textures[page].baseTexture, textureRect),
+ page,
};
}
diff --git a/src/loaders/bitmapFontParser.js b/src/loaders/bitmapFontParser.js
index 9691dd0..99e0c02 100644
--- a/src/loaders/bitmapFontParser.js
+++ b/src/loaders/bitmapFontParser.js
@@ -9,11 +9,11 @@
* @function parseBitmapFontData
* @memberof PIXI.loaders
* @param {PIXI.loaders.Resource} resource - Loader resource.
- * @param {PIXI.Texture} texture - Reference to texture.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
*/
-export function parse(resource, texture)
+export function parse(resource, textures)
{
- resource.bitmapFont = BitmapText.registerFont(resource.data, texture);
+ resource.bitmapFont = BitmapText.registerFont(resource.data, textures);
}
export default function ()
@@ -67,29 +67,53 @@
xmlUrl += '/';
}
- const textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');
+ const pages = resource.data.getElementsByTagName('page');
+ const textures = [];
+ const loadOptions = {
+ crossOrigin: resource.crossOrigin,
+ loadType: Resource.LOAD_TYPE.IMAGE,
+ metadata: resource.metadata.imageMetadata,
+ parentResource: resource,
+ };
- if (utils.TextureCache[textureUrl])
+ for (let x = 0; x < pages.length; ++x)
{
- // reuse existing texture
- parse(resource, utils.TextureCache[textureUrl]);
- next();
- }
- else
- {
- const loadOptions = {
- crossOrigin: resource.crossOrigin,
- loadType: Resource.LOAD_TYPE.IMAGE,
- metadata: resource.metadata.imageMetadata,
- parentResource: resource,
- };
+ const textureUrl = xmlUrl + pages[x].getAttribute('file');
- // load the texture for the font
- this.add(`${resource.name}_image`, textureUrl, loadOptions, (res) =>
+ if (utils.TextureCache[textureUrl])
{
- parse(resource, res.texture);
- next();
- });
+ textures.push(utils.TextureCache[textureUrl]);
+ }
+ else
+ {
+ // load the texture for the font
+ this.add(`${resource.name}_image${x}`, textureUrl, loadOptions, () =>
+ {
+ const nextTextures = [];
+
+ for (let x = 0; x < pages.length; ++x)
+ {
+ const nextTextureUrl = xmlUrl + pages[x].getAttribute('file');
+
+ if (utils.TextureCache[nextTextureUrl])
+ {
+ nextTextures.push(utils.TextureCache[nextTextureUrl]);
+ }
+ else
+ {
+ return;
+ }
+ }
+ parse(resource, nextTextures);
+ next();
+ });
+ }
+ }
+
+ if (textures.length === pages.length)
+ {
+ parse(resource, textures);
+ next();
}
};
}
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 96d9f44..b505250 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -503,10 +503,10 @@
*
* @static
* @param {XMLDocument} xml - The XML document data.
- * @param {PIXI.Texture} texture - Texture with all symbols.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
* @return {Object} Result font object with font, size, lineHeight and char fields.
*/
- static registerFont(xml, texture)
+ static registerFont(xml, textures)
{
const data = {};
const info = xml.getElementsByTagName('info')[0];
@@ -518,29 +518,44 @@
data.size = parseInt(info.getAttribute('size'), 10);
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res;
data.chars = {};
+ if (!(textures instanceof Array))
+ {
+ textures = [textures];
+ }
// parse letters
const letters = xml.getElementsByTagName('char');
+ let page;
for (let i = 0; i < letters.length; i++)
{
const letter = letters[i];
const charCode = parseInt(letter.getAttribute('id'), 10);
+ let textureRect;
- const textureRect = new core.Rectangle(
- (parseInt(letter.getAttribute('x'), 10) / res) + (texture.frame.x / res),
- (parseInt(letter.getAttribute('y'), 10) / res) + (texture.frame.y / res),
- parseInt(letter.getAttribute('width'), 10) / res,
- parseInt(letter.getAttribute('height'), 10) / res
- );
+ page = parseInt(letter.getAttribute('page'), 10);
+ if (isNaN(page))
+ {
+ textureRect = new core.Rectangle(0, 0, 0, 0);
+ page = 0;
+ }
+ else
+ {
+ textureRect = new core.Rectangle(
+ (parseInt(letter.getAttribute('x'), 10) / res) + (textures[page].frame.x / res),
+ (parseInt(letter.getAttribute('y'), 10) / res) + (textures[page].frame.y / res),
+ parseInt(letter.getAttribute('width'), 10) / res,
+ parseInt(letter.getAttribute('height'), 10) / res
+ );
+ }
data.chars[charCode] = {
xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res,
yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res,
xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res,
kerning: {},
- texture: new core.Texture(texture.baseTexture, textureRect),
-
+ texture: new core.Texture(textures[page].baseTexture, textureRect),
+ page,
};
}
diff --git a/src/loaders/bitmapFontParser.js b/src/loaders/bitmapFontParser.js
index 9691dd0..99e0c02 100644
--- a/src/loaders/bitmapFontParser.js
+++ b/src/loaders/bitmapFontParser.js
@@ -9,11 +9,11 @@
* @function parseBitmapFontData
* @memberof PIXI.loaders
* @param {PIXI.loaders.Resource} resource - Loader resource.
- * @param {PIXI.Texture} texture - Reference to texture.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
*/
-export function parse(resource, texture)
+export function parse(resource, textures)
{
- resource.bitmapFont = BitmapText.registerFont(resource.data, texture);
+ resource.bitmapFont = BitmapText.registerFont(resource.data, textures);
}
export default function ()
@@ -67,29 +67,53 @@
xmlUrl += '/';
}
- const textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');
+ const pages = resource.data.getElementsByTagName('page');
+ const textures = [];
+ const loadOptions = {
+ crossOrigin: resource.crossOrigin,
+ loadType: Resource.LOAD_TYPE.IMAGE,
+ metadata: resource.metadata.imageMetadata,
+ parentResource: resource,
+ };
- if (utils.TextureCache[textureUrl])
+ for (let x = 0; x < pages.length; ++x)
{
- // reuse existing texture
- parse(resource, utils.TextureCache[textureUrl]);
- next();
- }
- else
- {
- const loadOptions = {
- crossOrigin: resource.crossOrigin,
- loadType: Resource.LOAD_TYPE.IMAGE,
- metadata: resource.metadata.imageMetadata,
- parentResource: resource,
- };
+ const textureUrl = xmlUrl + pages[x].getAttribute('file');
- // load the texture for the font
- this.add(`${resource.name}_image`, textureUrl, loadOptions, (res) =>
+ if (utils.TextureCache[textureUrl])
{
- parse(resource, res.texture);
- next();
- });
+ textures.push(utils.TextureCache[textureUrl]);
+ }
+ else
+ {
+ // load the texture for the font
+ this.add(`${resource.name}_image${x}`, textureUrl, loadOptions, () =>
+ {
+ const nextTextures = [];
+
+ for (let x = 0; x < pages.length; ++x)
+ {
+ const nextTextureUrl = xmlUrl + pages[x].getAttribute('file');
+
+ if (utils.TextureCache[nextTextureUrl])
+ {
+ nextTextures.push(utils.TextureCache[nextTextureUrl]);
+ }
+ else
+ {
+ return;
+ }
+ }
+ parse(resource, nextTextures);
+ next();
+ });
+ }
+ }
+
+ if (textures.length === pages.length)
+ {
+ parse(resource, textures);
+ next();
}
};
}
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 70703fc..eb2e34f 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -307,6 +307,69 @@
done();
});
});
+
+ it('should properly register bitmap font having more than one texture', function (done)
+ {
+ const ldr = new PIXI.loaders.Loader();
+
+ ldr.add(`${__dirname}/resources/split_font.fnt`);
+ ldr.load(() =>
+ {
+ const font = PIXI.extras.BitmapText.fonts.split_font;
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.split_font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ let src = charA.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charA.texture.frame.x).to.equal(2);
+ expect(charA.texture.frame.y).to.equal(2);
+ expect(charA.texture.frame.width).to.equal(19);
+ expect(charA.texture.frame.height).to.equal(20);
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ src = charB.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charB.texture.frame.x).to.equal(2);
+ expect(charB.texture.frame.y).to.equal(24);
+ expect(charB.texture.frame.width).to.equal(15);
+ expect(charB.texture.frame.height).to.equal(20);
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ src = charC.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charC.texture.frame.x).to.equal(2);
+ expect(charC.texture.frame.y).to.equal(2);
+ expect(charC.texture.frame.width).to.equal(18);
+ expect(charC.texture.frame.height).to.equal(20);
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ src = charD.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charD.texture.frame.x).to.equal(2);
+ expect(charD.texture.frame.y).to.equal(24);
+ expect(charD.texture.frame.width).to.equal(17);
+ expect(charD.texture.frame.height).to.equal(20);
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+ });
});
describe('PIXI.loaders.parseBitmapFontData', function ()
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 96d9f44..b505250 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -503,10 +503,10 @@
*
* @static
* @param {XMLDocument} xml - The XML document data.
- * @param {PIXI.Texture} texture - Texture with all symbols.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
* @return {Object} Result font object with font, size, lineHeight and char fields.
*/
- static registerFont(xml, texture)
+ static registerFont(xml, textures)
{
const data = {};
const info = xml.getElementsByTagName('info')[0];
@@ -518,29 +518,44 @@
data.size = parseInt(info.getAttribute('size'), 10);
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res;
data.chars = {};
+ if (!(textures instanceof Array))
+ {
+ textures = [textures];
+ }
// parse letters
const letters = xml.getElementsByTagName('char');
+ let page;
for (let i = 0; i < letters.length; i++)
{
const letter = letters[i];
const charCode = parseInt(letter.getAttribute('id'), 10);
+ let textureRect;
- const textureRect = new core.Rectangle(
- (parseInt(letter.getAttribute('x'), 10) / res) + (texture.frame.x / res),
- (parseInt(letter.getAttribute('y'), 10) / res) + (texture.frame.y / res),
- parseInt(letter.getAttribute('width'), 10) / res,
- parseInt(letter.getAttribute('height'), 10) / res
- );
+ page = parseInt(letter.getAttribute('page'), 10);
+ if (isNaN(page))
+ {
+ textureRect = new core.Rectangle(0, 0, 0, 0);
+ page = 0;
+ }
+ else
+ {
+ textureRect = new core.Rectangle(
+ (parseInt(letter.getAttribute('x'), 10) / res) + (textures[page].frame.x / res),
+ (parseInt(letter.getAttribute('y'), 10) / res) + (textures[page].frame.y / res),
+ parseInt(letter.getAttribute('width'), 10) / res,
+ parseInt(letter.getAttribute('height'), 10) / res
+ );
+ }
data.chars[charCode] = {
xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res,
yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res,
xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res,
kerning: {},
- texture: new core.Texture(texture.baseTexture, textureRect),
-
+ texture: new core.Texture(textures[page].baseTexture, textureRect),
+ page,
};
}
diff --git a/src/loaders/bitmapFontParser.js b/src/loaders/bitmapFontParser.js
index 9691dd0..99e0c02 100644
--- a/src/loaders/bitmapFontParser.js
+++ b/src/loaders/bitmapFontParser.js
@@ -9,11 +9,11 @@
* @function parseBitmapFontData
* @memberof PIXI.loaders
* @param {PIXI.loaders.Resource} resource - Loader resource.
- * @param {PIXI.Texture} texture - Reference to texture.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
*/
-export function parse(resource, texture)
+export function parse(resource, textures)
{
- resource.bitmapFont = BitmapText.registerFont(resource.data, texture);
+ resource.bitmapFont = BitmapText.registerFont(resource.data, textures);
}
export default function ()
@@ -67,29 +67,53 @@
xmlUrl += '/';
}
- const textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');
+ const pages = resource.data.getElementsByTagName('page');
+ const textures = [];
+ const loadOptions = {
+ crossOrigin: resource.crossOrigin,
+ loadType: Resource.LOAD_TYPE.IMAGE,
+ metadata: resource.metadata.imageMetadata,
+ parentResource: resource,
+ };
- if (utils.TextureCache[textureUrl])
+ for (let x = 0; x < pages.length; ++x)
{
- // reuse existing texture
- parse(resource, utils.TextureCache[textureUrl]);
- next();
- }
- else
- {
- const loadOptions = {
- crossOrigin: resource.crossOrigin,
- loadType: Resource.LOAD_TYPE.IMAGE,
- metadata: resource.metadata.imageMetadata,
- parentResource: resource,
- };
+ const textureUrl = xmlUrl + pages[x].getAttribute('file');
- // load the texture for the font
- this.add(`${resource.name}_image`, textureUrl, loadOptions, (res) =>
+ if (utils.TextureCache[textureUrl])
{
- parse(resource, res.texture);
- next();
- });
+ textures.push(utils.TextureCache[textureUrl]);
+ }
+ else
+ {
+ // load the texture for the font
+ this.add(`${resource.name}_image${x}`, textureUrl, loadOptions, () =>
+ {
+ const nextTextures = [];
+
+ for (let x = 0; x < pages.length; ++x)
+ {
+ const nextTextureUrl = xmlUrl + pages[x].getAttribute('file');
+
+ if (utils.TextureCache[nextTextureUrl])
+ {
+ nextTextures.push(utils.TextureCache[nextTextureUrl]);
+ }
+ else
+ {
+ return;
+ }
+ }
+ parse(resource, nextTextures);
+ next();
+ });
+ }
+ }
+
+ if (textures.length === pages.length)
+ {
+ parse(resource, textures);
+ next();
}
};
}
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 70703fc..eb2e34f 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -307,6 +307,69 @@
done();
});
});
+
+ it('should properly register bitmap font having more than one texture', function (done)
+ {
+ const ldr = new PIXI.loaders.Loader();
+
+ ldr.add(`${__dirname}/resources/split_font.fnt`);
+ ldr.load(() =>
+ {
+ const font = PIXI.extras.BitmapText.fonts.split_font;
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.split_font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ let src = charA.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charA.texture.frame.x).to.equal(2);
+ expect(charA.texture.frame.y).to.equal(2);
+ expect(charA.texture.frame.width).to.equal(19);
+ expect(charA.texture.frame.height).to.equal(20);
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ src = charB.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charB.texture.frame.x).to.equal(2);
+ expect(charB.texture.frame.y).to.equal(24);
+ expect(charB.texture.frame.width).to.equal(15);
+ expect(charB.texture.frame.height).to.equal(20);
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ src = charC.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charC.texture.frame.x).to.equal(2);
+ expect(charC.texture.frame.y).to.equal(2);
+ expect(charC.texture.frame.width).to.equal(18);
+ expect(charC.texture.frame.height).to.equal(20);
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ src = charD.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charD.texture.frame.x).to.equal(2);
+ expect(charD.texture.frame.y).to.equal(24);
+ expect(charD.texture.frame.width).to.equal(17);
+ expect(charD.texture.frame.height).to.equal(20);
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+ });
});
describe('PIXI.loaders.parseBitmapFontData', function ()
diff --git a/test/loaders/resources/split_font.fnt b/test/loaders/resources/split_font.fnt
new file mode 100644
index 0000000..35cbf49
--- /dev/null
+++ b/test/loaders/resources/split_font.fnt
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 96d9f44..b505250 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -503,10 +503,10 @@
*
* @static
* @param {XMLDocument} xml - The XML document data.
- * @param {PIXI.Texture} texture - Texture with all symbols.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
* @return {Object} Result font object with font, size, lineHeight and char fields.
*/
- static registerFont(xml, texture)
+ static registerFont(xml, textures)
{
const data = {};
const info = xml.getElementsByTagName('info')[0];
@@ -518,29 +518,44 @@
data.size = parseInt(info.getAttribute('size'), 10);
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res;
data.chars = {};
+ if (!(textures instanceof Array))
+ {
+ textures = [textures];
+ }
// parse letters
const letters = xml.getElementsByTagName('char');
+ let page;
for (let i = 0; i < letters.length; i++)
{
const letter = letters[i];
const charCode = parseInt(letter.getAttribute('id'), 10);
+ let textureRect;
- const textureRect = new core.Rectangle(
- (parseInt(letter.getAttribute('x'), 10) / res) + (texture.frame.x / res),
- (parseInt(letter.getAttribute('y'), 10) / res) + (texture.frame.y / res),
- parseInt(letter.getAttribute('width'), 10) / res,
- parseInt(letter.getAttribute('height'), 10) / res
- );
+ page = parseInt(letter.getAttribute('page'), 10);
+ if (isNaN(page))
+ {
+ textureRect = new core.Rectangle(0, 0, 0, 0);
+ page = 0;
+ }
+ else
+ {
+ textureRect = new core.Rectangle(
+ (parseInt(letter.getAttribute('x'), 10) / res) + (textures[page].frame.x / res),
+ (parseInt(letter.getAttribute('y'), 10) / res) + (textures[page].frame.y / res),
+ parseInt(letter.getAttribute('width'), 10) / res,
+ parseInt(letter.getAttribute('height'), 10) / res
+ );
+ }
data.chars[charCode] = {
xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res,
yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res,
xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res,
kerning: {},
- texture: new core.Texture(texture.baseTexture, textureRect),
-
+ texture: new core.Texture(textures[page].baseTexture, textureRect),
+ page,
};
}
diff --git a/src/loaders/bitmapFontParser.js b/src/loaders/bitmapFontParser.js
index 9691dd0..99e0c02 100644
--- a/src/loaders/bitmapFontParser.js
+++ b/src/loaders/bitmapFontParser.js
@@ -9,11 +9,11 @@
* @function parseBitmapFontData
* @memberof PIXI.loaders
* @param {PIXI.loaders.Resource} resource - Loader resource.
- * @param {PIXI.Texture} texture - Reference to texture.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
*/
-export function parse(resource, texture)
+export function parse(resource, textures)
{
- resource.bitmapFont = BitmapText.registerFont(resource.data, texture);
+ resource.bitmapFont = BitmapText.registerFont(resource.data, textures);
}
export default function ()
@@ -67,29 +67,53 @@
xmlUrl += '/';
}
- const textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');
+ const pages = resource.data.getElementsByTagName('page');
+ const textures = [];
+ const loadOptions = {
+ crossOrigin: resource.crossOrigin,
+ loadType: Resource.LOAD_TYPE.IMAGE,
+ metadata: resource.metadata.imageMetadata,
+ parentResource: resource,
+ };
- if (utils.TextureCache[textureUrl])
+ for (let x = 0; x < pages.length; ++x)
{
- // reuse existing texture
- parse(resource, utils.TextureCache[textureUrl]);
- next();
- }
- else
- {
- const loadOptions = {
- crossOrigin: resource.crossOrigin,
- loadType: Resource.LOAD_TYPE.IMAGE,
- metadata: resource.metadata.imageMetadata,
- parentResource: resource,
- };
+ const textureUrl = xmlUrl + pages[x].getAttribute('file');
- // load the texture for the font
- this.add(`${resource.name}_image`, textureUrl, loadOptions, (res) =>
+ if (utils.TextureCache[textureUrl])
{
- parse(resource, res.texture);
- next();
- });
+ textures.push(utils.TextureCache[textureUrl]);
+ }
+ else
+ {
+ // load the texture for the font
+ this.add(`${resource.name}_image${x}`, textureUrl, loadOptions, () =>
+ {
+ const nextTextures = [];
+
+ for (let x = 0; x < pages.length; ++x)
+ {
+ const nextTextureUrl = xmlUrl + pages[x].getAttribute('file');
+
+ if (utils.TextureCache[nextTextureUrl])
+ {
+ nextTextures.push(utils.TextureCache[nextTextureUrl]);
+ }
+ else
+ {
+ return;
+ }
+ }
+ parse(resource, nextTextures);
+ next();
+ });
+ }
+ }
+
+ if (textures.length === pages.length)
+ {
+ parse(resource, textures);
+ next();
}
};
}
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 70703fc..eb2e34f 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -307,6 +307,69 @@
done();
});
});
+
+ it('should properly register bitmap font having more than one texture', function (done)
+ {
+ const ldr = new PIXI.loaders.Loader();
+
+ ldr.add(`${__dirname}/resources/split_font.fnt`);
+ ldr.load(() =>
+ {
+ const font = PIXI.extras.BitmapText.fonts.split_font;
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.split_font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ let src = charA.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charA.texture.frame.x).to.equal(2);
+ expect(charA.texture.frame.y).to.equal(2);
+ expect(charA.texture.frame.width).to.equal(19);
+ expect(charA.texture.frame.height).to.equal(20);
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ src = charB.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charB.texture.frame.x).to.equal(2);
+ expect(charB.texture.frame.y).to.equal(24);
+ expect(charB.texture.frame.width).to.equal(15);
+ expect(charB.texture.frame.height).to.equal(20);
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ src = charC.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charC.texture.frame.x).to.equal(2);
+ expect(charC.texture.frame.y).to.equal(2);
+ expect(charC.texture.frame.width).to.equal(18);
+ expect(charC.texture.frame.height).to.equal(20);
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ src = charD.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charD.texture.frame.x).to.equal(2);
+ expect(charD.texture.frame.y).to.equal(24);
+ expect(charD.texture.frame.width).to.equal(17);
+ expect(charD.texture.frame.height).to.equal(20);
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+ });
});
describe('PIXI.loaders.parseBitmapFontData', function ()
diff --git a/test/loaders/resources/split_font.fnt b/test/loaders/resources/split_font.fnt
new file mode 100644
index 0000000..35cbf49
--- /dev/null
+++ b/test/loaders/resources/split_font.fnt
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/loaders/resources/split_font_ab.png b/test/loaders/resources/split_font_ab.png
new file mode 100644
index 0000000..dca6137
--- /dev/null
+++ b/test/loaders/resources/split_font_ab.png
Binary files differ
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 96d9f44..b505250 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -503,10 +503,10 @@
*
* @static
* @param {XMLDocument} xml - The XML document data.
- * @param {PIXI.Texture} texture - Texture with all symbols.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
* @return {Object} Result font object with font, size, lineHeight and char fields.
*/
- static registerFont(xml, texture)
+ static registerFont(xml, textures)
{
const data = {};
const info = xml.getElementsByTagName('info')[0];
@@ -518,29 +518,44 @@
data.size = parseInt(info.getAttribute('size'), 10);
data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10) / res;
data.chars = {};
+ if (!(textures instanceof Array))
+ {
+ textures = [textures];
+ }
// parse letters
const letters = xml.getElementsByTagName('char');
+ let page;
for (let i = 0; i < letters.length; i++)
{
const letter = letters[i];
const charCode = parseInt(letter.getAttribute('id'), 10);
+ let textureRect;
- const textureRect = new core.Rectangle(
- (parseInt(letter.getAttribute('x'), 10) / res) + (texture.frame.x / res),
- (parseInt(letter.getAttribute('y'), 10) / res) + (texture.frame.y / res),
- parseInt(letter.getAttribute('width'), 10) / res,
- parseInt(letter.getAttribute('height'), 10) / res
- );
+ page = parseInt(letter.getAttribute('page'), 10);
+ if (isNaN(page))
+ {
+ textureRect = new core.Rectangle(0, 0, 0, 0);
+ page = 0;
+ }
+ else
+ {
+ textureRect = new core.Rectangle(
+ (parseInt(letter.getAttribute('x'), 10) / res) + (textures[page].frame.x / res),
+ (parseInt(letter.getAttribute('y'), 10) / res) + (textures[page].frame.y / res),
+ parseInt(letter.getAttribute('width'), 10) / res,
+ parseInt(letter.getAttribute('height'), 10) / res
+ );
+ }
data.chars[charCode] = {
xOffset: parseInt(letter.getAttribute('xoffset'), 10) / res,
yOffset: parseInt(letter.getAttribute('yoffset'), 10) / res,
xAdvance: parseInt(letter.getAttribute('xadvance'), 10) / res,
kerning: {},
- texture: new core.Texture(texture.baseTexture, textureRect),
-
+ texture: new core.Texture(textures[page].baseTexture, textureRect),
+ page,
};
}
diff --git a/src/loaders/bitmapFontParser.js b/src/loaders/bitmapFontParser.js
index 9691dd0..99e0c02 100644
--- a/src/loaders/bitmapFontParser.js
+++ b/src/loaders/bitmapFontParser.js
@@ -9,11 +9,11 @@
* @function parseBitmapFontData
* @memberof PIXI.loaders
* @param {PIXI.loaders.Resource} resource - Loader resource.
- * @param {PIXI.Texture} texture - Reference to texture.
+ * @param {PIXI.Texture|PIXI.Texture[]} textures - List of textures for each page.
*/
-export function parse(resource, texture)
+export function parse(resource, textures)
{
- resource.bitmapFont = BitmapText.registerFont(resource.data, texture);
+ resource.bitmapFont = BitmapText.registerFont(resource.data, textures);
}
export default function ()
@@ -67,29 +67,53 @@
xmlUrl += '/';
}
- const textureUrl = xmlUrl + resource.data.getElementsByTagName('page')[0].getAttribute('file');
+ const pages = resource.data.getElementsByTagName('page');
+ const textures = [];
+ const loadOptions = {
+ crossOrigin: resource.crossOrigin,
+ loadType: Resource.LOAD_TYPE.IMAGE,
+ metadata: resource.metadata.imageMetadata,
+ parentResource: resource,
+ };
- if (utils.TextureCache[textureUrl])
+ for (let x = 0; x < pages.length; ++x)
{
- // reuse existing texture
- parse(resource, utils.TextureCache[textureUrl]);
- next();
- }
- else
- {
- const loadOptions = {
- crossOrigin: resource.crossOrigin,
- loadType: Resource.LOAD_TYPE.IMAGE,
- metadata: resource.metadata.imageMetadata,
- parentResource: resource,
- };
+ const textureUrl = xmlUrl + pages[x].getAttribute('file');
- // load the texture for the font
- this.add(`${resource.name}_image`, textureUrl, loadOptions, (res) =>
+ if (utils.TextureCache[textureUrl])
{
- parse(resource, res.texture);
- next();
- });
+ textures.push(utils.TextureCache[textureUrl]);
+ }
+ else
+ {
+ // load the texture for the font
+ this.add(`${resource.name}_image${x}`, textureUrl, loadOptions, () =>
+ {
+ const nextTextures = [];
+
+ for (let x = 0; x < pages.length; ++x)
+ {
+ const nextTextureUrl = xmlUrl + pages[x].getAttribute('file');
+
+ if (utils.TextureCache[nextTextureUrl])
+ {
+ nextTextures.push(utils.TextureCache[nextTextureUrl]);
+ }
+ else
+ {
+ return;
+ }
+ }
+ parse(resource, nextTextures);
+ next();
+ });
+ }
+ }
+
+ if (textures.length === pages.length)
+ {
+ parse(resource, textures);
+ next();
}
};
}
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 70703fc..eb2e34f 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -307,6 +307,69 @@
done();
});
});
+
+ it('should properly register bitmap font having more than one texture', function (done)
+ {
+ const ldr = new PIXI.loaders.Loader();
+
+ ldr.add(`${__dirname}/resources/split_font.fnt`);
+ ldr.load(() =>
+ {
+ const font = PIXI.extras.BitmapText.fonts.split_font;
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.split_font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ let src = charA.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charA.texture.frame.x).to.equal(2);
+ expect(charA.texture.frame.y).to.equal(2);
+ expect(charA.texture.frame.width).to.equal(19);
+ expect(charA.texture.frame.height).to.equal(20);
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ src = charB.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_ab.png');
+ expect(charB.texture.frame.x).to.equal(2);
+ expect(charB.texture.frame.y).to.equal(24);
+ expect(charB.texture.frame.width).to.equal(15);
+ expect(charB.texture.frame.height).to.equal(20);
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ src = charC.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charC.texture.frame.x).to.equal(2);
+ expect(charC.texture.frame.y).to.equal(2);
+ expect(charC.texture.frame.width).to.equal(18);
+ expect(charC.texture.frame.height).to.equal(20);
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ src = charD.texture.baseTexture.source.src;
+
+ src = src.substring(src.length - 17);
+ expect(src).to.equal('split_font_cd.png');
+ expect(charD.texture.frame.x).to.equal(2);
+ expect(charD.texture.frame.y).to.equal(24);
+ expect(charD.texture.frame.width).to.equal(17);
+ expect(charD.texture.frame.height).to.equal(20);
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+ });
});
describe('PIXI.loaders.parseBitmapFontData', function ()
diff --git a/test/loaders/resources/split_font.fnt b/test/loaders/resources/split_font.fnt
new file mode 100644
index 0000000..35cbf49
--- /dev/null
+++ b/test/loaders/resources/split_font.fnt
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/loaders/resources/split_font_ab.png b/test/loaders/resources/split_font_ab.png
new file mode 100644
index 0000000..dca6137
--- /dev/null
+++ b/test/loaders/resources/split_font_ab.png
Binary files differ
diff --git a/test/loaders/resources/split_font_cd.png b/test/loaders/resources/split_font_cd.png
new file mode 100644
index 0000000..8f3c77e
--- /dev/null
+++ b/test/loaders/resources/split_font_cd.png
Binary files differ