diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/test/loaders/resources/atlas@0.5x.json b/test/loaders/resources/atlas@0.5x.json
new file mode 100644
index 0000000..ae990a1
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas@0.5x.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/test/loaders/resources/atlas@0.5x.json b/test/loaders/resources/atlas@0.5x.json
new file mode 100644
index 0000000..ae990a1
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas@0.5x.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas@0.5x.png b/test/loaders/resources/atlas@0.5x.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.png
Binary files differ
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/test/loaders/resources/atlas@0.5x.json b/test/loaders/resources/atlas@0.5x.json
new file mode 100644
index 0000000..ae990a1
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas@0.5x.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas@0.5x.png b/test/loaders/resources/atlas@0.5x.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.png
Binary files differ
diff --git a/test/loaders/resources/font.fnt b/test/loaders/resources/font.fnt
new file mode 100644
index 0000000..56e1060
--- /dev/null
+++ b/test/loaders/resources/font.fnt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/test/loaders/resources/atlas@0.5x.json b/test/loaders/resources/atlas@0.5x.json
new file mode 100644
index 0000000..ae990a1
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas@0.5x.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas@0.5x.png b/test/loaders/resources/atlas@0.5x.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.png
Binary files differ
diff --git a/test/loaders/resources/font.fnt b/test/loaders/resources/font.fnt
new file mode 100644
index 0000000..56e1060
--- /dev/null
+++ b/test/loaders/resources/font.fnt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/loaders/resources/font.png b/test/loaders/resources/font.png
new file mode 100644
index 0000000..cf772e9
--- /dev/null
+++ b/test/loaders/resources/font.png
Binary files differ
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/test/loaders/resources/atlas@0.5x.json b/test/loaders/resources/atlas@0.5x.json
new file mode 100644
index 0000000..ae990a1
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas@0.5x.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas@0.5x.png b/test/loaders/resources/atlas@0.5x.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.png
Binary files differ
diff --git a/test/loaders/resources/font.fnt b/test/loaders/resources/font.fnt
new file mode 100644
index 0000000..56e1060
--- /dev/null
+++ b/test/loaders/resources/font.fnt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/loaders/resources/font.png b/test/loaders/resources/font.png
new file mode 100644
index 0000000..cf772e9
--- /dev/null
+++ b/test/loaders/resources/font.png
Binary files differ
diff --git a/test/loaders/resources/font@0.5x.fnt b/test/loaders/resources/font@0.5x.fnt
new file mode 100644
index 0000000..6c247c7
--- /dev/null
+++ b/test/loaders/resources/font@0.5x.fnt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/core/math/GroupD8.js b/src/core/math/GroupD8.js
index 50c2f31..e6a09e7 100644
--- a/src/core/math/GroupD8.js
+++ b/src/core/math/GroupD8.js
@@ -111,13 +111,14 @@
rotate180: (rotation) => rotation ^ 4,
/**
- * I dont know why sometimes width and heights needs to be swapped. We'll fix it later.
+ * Direction of main vector can be horizontal, vertical or diagonal.
+ * Some objects work with vertical directions different.
*
* @memberof PIXI.GroupD8
* @param {number} rotation - The number to check.
- * @returns {boolean} Whether or not the width/height should be swapped.
+ * @returns {boolean} Whether or not the direction is vertical
*/
- isSwapWidthHeight: (rotation) => (rotation & 3) === 2,
+ isVertical: (rotation) => (rotation & 3) === 2,
/**
* @memberof PIXI.GroupD8
diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js
index 4d95e15..2420a7d 100644
--- a/src/core/renderers/webgl/WebGLRenderer.js
+++ b/src/core/renderers/webgl/WebGLRenderer.js
@@ -266,6 +266,7 @@
reset()
{
this.runners.reset.run();
+
return this;
}
diff --git a/src/core/renderers/webgl/filters/Filter.js b/src/core/renderers/webgl/filters/Filter.js
index 5e065e2..7cd460c 100644
--- a/src/core/renderers/webgl/filters/Filter.js
+++ b/src/core/renderers/webgl/filters/Filter.js
@@ -2,6 +2,8 @@
import Program from '../../../shader/Program';
import { BLEND_MODES } from '../../../const';
import settings from '../../../settings';
+import { uid } from '../../../utils';
+import extractUniformsFromSrc from './extractUniformsFromSrc';
// let math = require('../../../math');
/**
@@ -49,12 +51,12 @@
this.glShaders = {};
// used for cacheing.. sure there is a better way!
- if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
+ if (!Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc])
{
- SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
+ Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
- this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
+ this.glShaderKey = Filter.SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
@@ -185,3 +187,12 @@
].join('\n');
}
}
+
+/**
+ * Used for caching shader IDs
+ *
+ * @static
+ * @private
+ */
+Filter.SOURCE_KEY_MAP = {};
+
diff --git a/src/core/renderers/webgl/systems/StencilSystem.js b/src/core/renderers/webgl/systems/StencilSystem.js
index 5c4ca3f..3843739 100644
--- a/src/core/renderers/webgl/systems/StencilSystem.js
+++ b/src/core/renderers/webgl/systems/StencilSystem.js
@@ -125,6 +125,6 @@
{
super.destroy(this);
- this.stencilMaskStack.stencilStack = null;
+ this.stencilMaskStack = null;
}
}
diff --git a/src/deprecation.js b/src/deprecation.js
index d1b689e..209910a 100644
--- a/src/deprecation.js
+++ b/src/deprecation.js
@@ -601,6 +601,21 @@
return this.generateCanvasTexture(scaleMode, resolution);
};
+ /**
+ * @method
+ * @name PIXI.GroupD8.isSwapWidthHeight
+ * @see PIXI.GroupD8.isVertical
+ * @param {number} rotation - The number to check.
+ * @returns {boolean} Whether or not the direction is vertical
+ * @deprecated since version 4.6.0
+ */
+ core.GroupD8.isSwapWidthHeight = function isSwapWidthHeight(rotation)
+ {
+ warn('GroupD8.isSwapWidthHeight was renamed to GroupD8.isVertical');
+
+ return core.GroupD8.isVertical(rotation);
+ };
+
core.RenderTexture.prototype.render = function render(displayObject, matrix, clear, updateTransform)
{
this.legacyRenderer.render(displayObject, this, clear, matrix, !updateTransform);
diff --git a/src/extras/BitmapText.js b/src/extras/BitmapText.js
index 0592b54..96d9f44 100644
--- a/src/extras/BitmapText.js
+++ b/src/extras/BitmapText.js
@@ -1,5 +1,6 @@
import * as core from '../core';
import ObservablePoint from '../core/math/ObservablePoint';
+import { getResolutionOfUrl } from '../core/utils';
import settings from '../core/settings';
/**
@@ -510,7 +511,8 @@
const data = {};
const info = xml.getElementsByTagName('info')[0];
const common = xml.getElementsByTagName('common')[0];
- const res = texture.baseTexture.resolution || settings.RESOLUTION;
+ const fileName = xml.getElementsByTagName('page')[0].getAttribute('file');
+ const res = getResolutionOfUrl(fileName, settings.RESOLUTION);
data.font = info.getAttribute('face');
data.size = parseInt(info.getAttribute('size'), 10);
diff --git a/test/interaction/InteractionManager.js b/test/interaction/InteractionManager.js
index 3f84d6a..136640e 100644
--- a/test/interaction/InteractionManager.js
+++ b/test/interaction/InteractionManager.js
@@ -279,13 +279,48 @@
removeSpy.restore();
});
- it('should add and remove pointer events to element', function ()
+ it('should add and remove pointer events to element seven times when touch events are supported', function ()
{
const manager = new PIXI.interaction.InteractionManager(sinon.stub());
const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
manager.interactionDOMElement = element;
manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = true;
+
+ manager.addEvents();
+
+ expect(element.addEventListener).to.have.been.callCount(7);
+ expect(element.addEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.addEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.addEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.addEventListener).to.have.been.calledWith('touchstart');
+ expect(element.addEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.addEventListener).to.have.been.calledWith('touchend');
+ expect(element.addEventListener).to.have.been.calledWith('touchmove');
+
+ manager.removeEvents();
+
+ expect(element.removeEventListener).to.have.been.callCount(7);
+ expect(element.removeEventListener).to.have.been.calledWith('pointerdown');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerleave');
+ expect(element.removeEventListener).to.have.been.calledWith('pointerover');
+
+ expect(element.removeEventListener).to.have.been.calledWith('touchstart');
+ expect(element.removeEventListener).to.have.been.calledWith('touchcancel');
+ expect(element.removeEventListener).to.have.been.calledWith('touchend');
+ expect(element.removeEventListener).to.have.been.calledWith('touchmove');
+ });
+
+ it('should add and remove pointer events to element three times when touch events are not supported', function ()
+ {
+ const manager = new PIXI.interaction.InteractionManager(sinon.stub());
+ const element = { style: {}, addEventListener: sinon.stub(), removeEventListener: sinon.stub() };
+
+ manager.interactionDOMElement = element;
+ manager.supportsPointerEvents = true;
+ manager.supportsTouchEvents = false;
manager.addEvents();
diff --git a/test/loaders/bitmapFontParser.js b/test/loaders/bitmapFontParser.js
index 7c77343..70703fc 100644
--- a/test/loaders/bitmapFontParser.js
+++ b/test/loaders/bitmapFontParser.js
@@ -1,7 +1,81 @@
'use strict';
+const path = require('path');
+const fs = require('fs');
+
describe('PIXI.loaders.bitmapFontParser', function ()
{
+ afterEach(function ()
+ {
+ for (var font in PIXI.extras.BitmapText.fonts)
+ {
+ delete PIXI.extras.BitmapText.fonts[font];
+ }
+ for (var baseTexture in PIXI.utils.BaseTextureCache)
+ {
+ delete PIXI.utils.BaseTextureCache[baseTexture];
+ }
+ for (var texture in PIXI.utils.TextureCache)
+ {
+ delete PIXI.utils.TextureCache[texture];
+ }
+ });
+
+ before(function (done)
+ {
+ const resolveURL = (url) => path.resolve(this.resources, url);
+
+ this.resources = path.join(__dirname, 'resources');
+ this.fontXML = null;
+ this.fontScaledXML = null;
+ this.fontImage = null;
+ this.fontScaledImage = null;
+ this.atlasImage = null;
+ this.atlasScaledImage = null;
+ this.atlasJSON = require(resolveURL('atlas.json')); // eslint-disable-line global-require
+ this.atlasScaledJSON = require(resolveURL('atlas@0.5x.json')); // eslint-disable-line global-require
+
+ const loadXML = (url) => new Promise((resolve) =>
+ fs.readFile(resolveURL(url), 'utf8', (err, data) =>
+ {
+ expect(err).to.be.null;
+ resolve((new window.DOMParser()).parseFromString(data, 'text/xml'));
+ }));
+
+ const loadImage = (url) => new Promise((resolve) =>
+ {
+ const image = new Image();
+
+ image.onload = () => resolve(image);
+ image.src = resolveURL(url);
+ });
+
+ Promise.all([
+ loadXML('font.fnt'),
+ loadXML('font@0.5x.fnt'),
+ loadImage('font.png'),
+ loadImage('font@0.5x.png'),
+ loadImage('atlas.png'),
+ loadImage('atlas@0.5x.png'),
+ ]).then(([
+ fontXML,
+ fontScaledXML,
+ fontImage,
+ fontScaledImage,
+ atlasImage,
+ atlasScaledImage,
+ ]) =>
+ {
+ this.fontXML = fontXML;
+ this.fontScaledXML = fontScaledXML;
+ this.fontImage = fontImage;
+ this.fontScaledImage = fontScaledImage;
+ this.atlasImage = atlasImage;
+ this.atlasScaledImage = atlasScaledImage;
+ done();
+ });
+ });
+
it('should exist and return a function', function ()
{
expect(PIXI.loaders.bitmapFontParser).to.be.a('function');
@@ -33,6 +107,206 @@
// TODO: Test the texture cache code path.
// TODO: Test the loading texture code path.
// TODO: Test data-url code paths.
+
+ it('should properly register bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontImage, null, 1));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontImage);
+ 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charC.texture.frame.x).to.equal(23);
+ 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontImage);
+ expect(charD.texture.frame.x).to.equal(19);
+ 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();
+ });
+
+ it('should properly register SCALED bitmap font', function (done)
+ {
+ const texture = new PIXI.Texture(new PIXI.BaseTexture(this.fontScaledImage, null, 0.5));
+ const font = PIXI.extras.BitmapText.registerFont(this.fontScaledXML, texture);
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charA.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charA.texture.frame.width).to.equal(38); // 19 / 0.5
+ expect(charA.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charB = font.chars['B'.charCodeAt(0) || 66];
+
+ expect(charB).to.exist;
+ expect(charB.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charB.texture.frame.x).to.equal(4); // 2 / 0.5
+ expect(charB.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charB.texture.frame.width).to.equal(30); // 15 / 0.5
+ expect(charB.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charC = font.chars['C'.charCodeAt(0) || 67];
+
+ expect(charC).to.exist;
+ expect(charC.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charC.texture.frame.x).to.equal(46); // 23 / 0.5
+ expect(charC.texture.frame.y).to.equal(4); // 2 / 0.5
+ expect(charC.texture.frame.width).to.equal(36); // 18 / 0.5
+ expect(charC.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charD = font.chars['D'.charCodeAt(0) || 68];
+
+ expect(charD).to.exist;
+ expect(charD.texture.baseTexture.source).to.equal(this.fontScaledImage);
+ expect(charD.texture.frame.x).to.equal(38); // 19 / 0.5
+ expect(charD.texture.frame.y).to.equal(48); // 24 / 0.5
+ expect(charD.texture.frame.width).to.equal(34); // 17 / 0.5
+ expect(charD.texture.frame.height).to.equal(40); // 20 / 0.5
+ const charE = font.chars['E'.charCodeAt(0) || 69];
+
+ expect(charE).to.be.undefined;
+ done();
+ });
+
+ it('should properly register bitmap font NESTED into spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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();
+ });
+ });
+
+ it('should properly register bitmap font NESTED into SCALED spritesheet', function (done)
+ {
+ const baseTexture = new PIXI.BaseTexture(this.atlasScaledImage, null, 1);
+ const spritesheet = new PIXI.Spritesheet(baseTexture, this.atlasScaledJSON);
+
+ spritesheet.parse(() =>
+ {
+ const fontTexture = PIXI.Texture.fromFrame('resources/font.png');
+ const font = PIXI.extras.BitmapText.registerFont(this.fontXML, fontTexture);
+ const fontX = 158; // bare value from spritesheet frame
+ const fontY = 2; // bare value from spritesheet frame
+
+ expect(font).to.be.an.object;
+ expect(PIXI.extras.BitmapText.fonts.font).to.equal(font);
+ expect(font).to.have.property('chars');
+ const charA = font.chars['A'.charCodeAt(0) || 65];
+
+ expect(charA).to.exist;
+ expect(charA.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charA.texture.frame.x).to.equal(fontX + 2);
+ expect(charA.texture.frame.y).to.equal(fontY + 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;
+ expect(charB.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charB.texture.frame.x).to.equal(fontX + 2);
+ expect(charB.texture.frame.y).to.equal(fontY + 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;
+ expect(charC.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charC.texture.frame.x).to.equal(fontX + 23);
+ expect(charC.texture.frame.y).to.equal(fontY + 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;
+ expect(charD.texture.baseTexture.source).to.equal(this.atlasScaledImage);
+ expect(charD.texture.frame.x).to.equal(fontX + 19);
+ expect(charD.texture.frame.y).to.equal(fontY + 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/atlas.json b/test/loaders/resources/atlas.json
new file mode 100644
index 0000000..86e65a5
--- /dev/null
+++ b/test/loaders/resources/atlas.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas.png b/test/loaders/resources/atlas.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas.png
Binary files differ
diff --git a/test/loaders/resources/atlas@0.5x.json b/test/loaders/resources/atlas@0.5x.json
new file mode 100644
index 0000000..ae990a1
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.json
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "image": "atlas@0.5x.png",
+ "size": {"w":256,"h":256},
+ "scale": "1"
+ },
+ "frames": {
+ "resources/test.png":
+ {
+ "frame": {"x":2,"y":2,"w":152,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":74,"y":36,"w":152,"h":188},
+ "sourceSize": {"w":300,"h":225}
+ },
+ "resources/font.png":
+ {
+ "frame": {"x":158,"y":2,"w":40,"h":42},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":2,"y":2,"w":40,"h":42},
+ "sourceSize": {"w":43,"h":46}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/loaders/resources/atlas@0.5x.png b/test/loaders/resources/atlas@0.5x.png
new file mode 100644
index 0000000..d5e7892
--- /dev/null
+++ b/test/loaders/resources/atlas@0.5x.png
Binary files differ
diff --git a/test/loaders/resources/font.fnt b/test/loaders/resources/font.fnt
new file mode 100644
index 0000000..56e1060
--- /dev/null
+++ b/test/loaders/resources/font.fnt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/loaders/resources/font.png b/test/loaders/resources/font.png
new file mode 100644
index 0000000..cf772e9
--- /dev/null
+++ b/test/loaders/resources/font.png
Binary files differ
diff --git a/test/loaders/resources/font@0.5x.fnt b/test/loaders/resources/font@0.5x.fnt
new file mode 100644
index 0000000..6c247c7
--- /dev/null
+++ b/test/loaders/resources/font@0.5x.fnt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/loaders/resources/font@0.5x.png b/test/loaders/resources/font@0.5x.png
new file mode 100644
index 0000000..cf772e9
--- /dev/null
+++ b/test/loaders/resources/font@0.5x.png
Binary files differ