Skip to content

Commit cc5740a

Browse files
committed
BitmapText line spacing and word wrapping has been vastly improved and bought in-line with how Pixi 3 handles it, but with additional anchor support.
1 parent 608e2b5 commit cc5740a

2 files changed

Lines changed: 53 additions & 28 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ Version 2.4 - "Katar" - in dev
303303

304304
### Updates
305305

306-
* TypeScript definitions fixes and updates (thanks @clark-stevenson @isuda @ggarek)
307-
* JSDoc typo fixes (thanks @robertpenner @luckylooke)
306+
* TypeScript definitions fixes and updates (thanks @clark-stevenson @isuda @ggarek @jamesgroat)
307+
* JSDoc typo fixes (thanks @robertpenner @luckylooke @asyncanup)
308308
* Added missing `resumed` method to Phaser.State class template.
309309
* Color.webToColor and Color.updateColor now updates the `out.color` and `out.color32` properties (thanks @cuixiping #1728)
310310
* Tilemap.createFromObjects has been updated for Tiled 0.11 and can now look-up object layers based on id, uid or name. It will also now copy over Sprite scaling properties if set (thanks @mandarinx #1738)
@@ -338,6 +338,7 @@ Version 2.4 - "Katar" - in dev
338338
* PIXI.Sprite.tintedTexture contains a canvas object that holds the tinted version of the Sprite. This is only populated in Canvas, not in WebGL.
339339
* ScaleManager.scaleSprite will no longer try and scale a display object that doesn't have a scale property.
340340
* The LoadTexture component has a new property `customRender` which is checked for in the Core postUpdate to know when to render custom elements like Videos.
341+
* BitmapText line spacing and word wrapping has been vastly improved and bought in-line with how Pixi 3 handles it, but with additional anchor support.
341342

342343
### Bug Fixes
343344

src/pixi/text/BitmapText.js

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PIXI.BitmapText = function(text, style)
2121
PIXI.DisplayObjectContainer.call(this);
2222

2323
/**
24-
* [read-only] The width of the overall text, different from fontSize,
24+
* The width of the overall text, different from fontSize,
2525
* which is defined in the style object
2626
*
2727
* @property textWidth
@@ -31,7 +31,7 @@ PIXI.BitmapText = function(text, style)
3131
this.textWidth = 0;
3232

3333
/**
34-
* [read-only] The height of the overall text, different from fontSize,
34+
* The height of the overall text, different from fontSize,
3535
* which is defined in the style object
3636
*
3737
* @property textHeight
@@ -62,11 +62,12 @@ PIXI.BitmapText = function(text, style)
6262
this._prevAnchor = new Phaser.Point(0, 0);
6363

6464
/**
65-
* @property _pool
66-
* @type Array
65+
* Private tracker for the letter sprite pool.
66+
*
67+
* @member {Sprite[]}
6768
* @private
6869
*/
69-
this._pool = [];
70+
this._glyphs = [];
7071

7172
this.setText(text);
7273
this.setStyle(style);
@@ -78,6 +79,7 @@ PIXI.BitmapText = function(text, style)
7879
* @type Boolean
7980
*/
8081
this.dirty = false;
82+
8183
};
8284

8385
// constructor
@@ -130,11 +132,12 @@ PIXI.BitmapText.prototype.updateText = function()
130132
var pos = new PIXI.Point();
131133
var prevCharCode = null;
132134
var chars = [];
135+
var lastLineWidth = 0;
133136
var maxLineWidth = 0;
134137
var lineWidths = [];
135138
var line = 0;
136139
var scale = this.fontSize / data.size;
137-
var lastSpace = 0;
140+
var lastSpace = -1;
138141

139142
for (var i = 0; i < this.text.length; i++)
140143
{
@@ -143,8 +146,8 @@ PIXI.BitmapText.prototype.updateText = function()
143146

144147
if (/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
145148
{
146-
lineWidths.push(pos.x);
147-
maxLineWidth = Math.max(maxLineWidth, pos.x);
149+
lineWidths.push(lastLineWidth);
150+
maxLineWidth = Math.max(maxLineWidth, lastLineWidth);
148151
line++;
149152

150153
pos.x = 0;
@@ -153,6 +156,7 @@ PIXI.BitmapText.prototype.updateText = function()
153156
continue;
154157
}
155158

159+
// This doesn't factor in the width of the current character
156160
if (lastSpace !== -1 && this.maxWidth > 0 && pos.x * scale > this.maxWidth)
157161
{
158162
chars.splice(lastSpace, i - lastSpace);
@@ -171,21 +175,33 @@ PIXI.BitmapText.prototype.updateText = function()
171175

172176
var charData = data.chars[charCode];
173177

174-
if(!charData) continue;
178+
if (!charData)
179+
{
180+
continue;
181+
}
175182

176-
if(prevCharCode && charData.kerning[prevCharCode])
183+
if (prevCharCode && charData.kerning[prevCharCode])
177184
{
178185
pos.x += charData.kerning[prevCharCode];
179186
}
180187

181-
chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)});
188+
chars.push({
189+
texture: charData.texture,
190+
line: line,
191+
charCode: charCode,
192+
position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)
193+
});
194+
195+
lastLineWidth = pos.x + (charData.texture.width + charData.xOffset);
182196
pos.x += charData.xAdvance;
183197

184198
prevCharCode = charCode;
185199
}
186200

187-
lineWidths.push(pos.x);
188-
maxLineWidth = Math.max(maxLineWidth, pos.x);
201+
lineWidths.push(lastLineWidth);
202+
maxLineWidth = Math.max(maxLineWidth, lastLineWidth);
203+
204+
console.log('maxLineWidth', maxLineWidth);
189205

190206
var lineAlignOffsets = [];
191207

@@ -205,39 +221,47 @@ PIXI.BitmapText.prototype.updateText = function()
205221
lineAlignOffsets.push(alignOffset);
206222
}
207223

208-
var lenChildren = this.children.length;
209224
var lenChars = chars.length;
210225
var tint = this.tint || 0xFFFFFF;
211226

212-
this.textWidth = maxLineWidth * scale;
213-
this.textHeight = (pos.y + data.lineHeight) * scale;
214-
215227
var ax = this.textWidth * this.anchor.x;
216228
var ay = this.textHeight * this.anchor.y;
217229

218230
for (i = 0; i < lenChars; i++)
219231
{
220-
var c = i < lenChildren ? this.children[i] : this._pool.pop(); // get old child if have. if not - take from pool.
232+
var c = this._glyphs[i]; // get the next glyph sprite
221233

222-
if (c) c.setTexture(chars[i].texture); // check if got one before.
223-
else c = new PIXI.Sprite(chars[i].texture); // if no create new one.
234+
if (c)
235+
{
236+
c.texture = chars[i].texture;
237+
}
238+
else
239+
{
240+
c = new PIXI.Sprite(chars[i].texture);
241+
this._glyphs.push(c);
242+
}
224243

225244
c.position.x = ((chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale) - ax;
226245
c.position.y = (chars[i].position.y * scale) - ay;
227246

228247
c.scale.x = c.scale.y = scale;
229248
c.tint = tint;
230-
if (!c.parent) this.addChild(c);
249+
250+
if (!c.parent)
251+
{
252+
this.addChild(c);
253+
}
231254
}
232255

233-
// Remove unnecessary children and put them into the pool
234-
while (this.children.length > lenChars)
256+
// Remove unnecessary children.
257+
for (i = lenChars; i < this._glyphs.length; ++i)
235258
{
236-
var child = this.getChildAt(this.children.length - 1);
237-
this._pool.push(child);
238-
this.removeChild(child);
259+
this.removeChild(this._glyphs[i]);
239260
}
240261

262+
this.textWidth = maxLineWidth * scale;
263+
this.textHeight = (pos.y + data.lineHeight) * scale;
264+
241265
};
242266

243267
/**

0 commit comments

Comments
 (0)