Closed jeichelbaum closed 8 years ago
Couple of sanity checks:
1) Is txt == null? (it shouldn't be, but if it is that's eye-opening) 2) Can you put a try/catch around the text assignment and get anything useful? 3) Does setting the text to null or the empty string give you different behavior? 4) If you don't add the text to the stage but keep the rest unchanged, do you get different behavior?
1) txt is not null 2) it still crashes even with try/catch 3) the app doesn't crash if I set txt.text = null; 4) that in fact changes something: only doing one of both actions, adding or setting the text, does not crash it but if I perform both (no matter what order), it crashes
Okay, so I bet this is an issue with text rendering. Just setting the text to some non-null value should not be an issue (what could possibly go wrong???) -- but by setting the text to something, AND adding it to stage, the engine later tries to render it, and then perhaps a recent change knocked something loose.
Let me see where you can make some further changes (perhaps inserting some traces in the TextField.hx class to see if you can get some output before the crash to see where it goes bad)
Unfortunately, I don't have an Android device so someone else will have to test this for me :( But I'm happy to help diagnose the issue.
Diagnostics:
Open openfl/_internal/renderer/opengl/GLTextField.hx
Add these traces (you can get trace output, right?):
public static function render (textField:TextField, renderSession:RenderSession) {
trace("render text a");
if (!textField.__renderable || textField.__worldAlpha <= 0) return;
trace("render text b");
TextFieldGraphics.render (textField);
text("render text c");
GraphicsRenderer.render (textField, renderSession);
text("render text d");
}
And see if some or all of those traces happen. That will narrow down where the error is since we don't get clean crash information telling us where things break.
narrowed it down till renderText()
it seems to crash, when trying to perform this: fontGlyphs.set (size, font.renderGlyphs (font.getGlyphs (), size));
hope that helps?!
okay, cool, if you've narrowed it down to that line, can you verify if font is null before it tries to call that?
neither font nor fontGlyphs is null
okay, so our problem is going to be in either renderGlyphs or font.getGlyphs.
Quickest thing is to do something like this
var temp = font.getGlyphs()
trace("temp == " + temp);
fontGlyphs.set(size,font.renderGlyphs(temp,size));
And see if that's null. If so we dive into getGlyphs, if not, renderGlyphs
temp is not null, but an array of integers
Okay, was afraid of that, guess we get to dive into renderGlyphs and figure out what thorny thing is going wrong.
Oh real quick -- what is size? (Making sure it's not 0 or -1 or something weird)
wish I could just copy paste but it wont let me do that
Ah I meant the size of the font you were passing in to fontGlyphs.set, not the size of the array
Oh haha Im sorry. It's 12
Okay so into renderglyphs() we go.
So not only is your array of glyphs not null, "Glyph" is just an abstract int, so none of the values can possibly be null either. Also your trace shows that in fact, non of them are null. And your fontSize is not weird.
So here's our next test.
public function renderGlyphs (glyphs:Array<Glyph>, fontSize:Int):Map<Glyph, Image> {
trace("a");
#if (cpp || neko || nodejs)
var uniqueGlyphs = new Map<Int, Bool> ();
for (glyph in glyphs) {
uniqueGlyphs.set (glyph, true);
}
var glyphList = [];
for (key in uniqueGlyphs.keys ()) {
glyphList.push (key);
}
trace("before lime_font_set_size("+src+","+fontSize+")");
lime_font_set_size (src, fontSize);
trace("after lime_font_set_size");
var bytes = new ByteArray ();
bytes.endian = "littleEndian";
if (lime_font_render_glyphs (src, glyphList, bytes)) {
trace("inside big if block");
bytes.position = 0;
var count = bytes.readUnsignedInt ();
var bufferWidth = 128;
var bufferHeight = 128;
var offsetX = 0;
var offsetY = 0;
var maxRows = 0;
var width, height;
var i = 0;
trace("before while loop");
while (i < count) {
bytes.position += 4;
width = bytes.readUnsignedInt ();
height = bytes.readUnsignedInt ();
bytes.position += (4 * 2) + width * height;
if (offsetX + width > bufferWidth) {
offsetY += maxRows + 1;
offsetX = 0;
maxRows = 0;
}
if (offsetY + height > bufferHeight) {
if (bufferWidth < bufferHeight) {
bufferWidth *= 2;
} else {
bufferHeight *= 2;
}
offsetX = 0;
offsetY = 0;
maxRows = 0;
// TODO: make this better
bytes.position = 4;
i = 0;
continue;
}
offsetX += width + 1;
if (height > maxRows) {
maxRows = height;
}
i++;
}
trace("after while loop");
var map = new Map<Int, Image> ();
var buffer = new ImageBuffer (null, bufferWidth, bufferHeight, 1);
var data = new ByteArray (bufferWidth * bufferHeight);
bytes.position = 4;
offsetX = 0;
offsetY = 0;
maxRows = 0;
var index, x, y, image;
trace("before for loop");
for (i in 0...count) {
index = bytes.readUnsignedInt ();
width = bytes.readUnsignedInt ();
height = bytes.readUnsignedInt ();
x = bytes.readUnsignedInt ();
y = bytes.readUnsignedInt ();
if (offsetX + width > bufferWidth) {
offsetY += maxRows + 1;
offsetX = 0;
maxRows = 0;
}
for (i in 0...height) {
data.position = ((i + offsetY) * bufferWidth) + offsetX;
//bytes.readBytes (data, 0, width);
for (x in 0...width) {
var byte = bytes.readUnsignedByte ();
data.writeByte (byte);
}
}
image = new Image (buffer, offsetX, offsetY, width, height);
image.x = x;
image.y = y;
map.set (index, image);
offsetX += width + 1;
if (height > maxRows) {
maxRows = height;
}
}
trace("after for loop");
#if js
buffer.data = data.byteView;
#else
buffer.data = new UInt8Array (data);
#end
return map;
}
trace("z");
#end
trace("fall through null");
return null;
}
If you want to be super thorough, put some traces in the for and while loops that print out the iterator value, but even the above should narrow it down pretty good.
I don't know what it's worth, but when I was experiencing the same bug in #613, adding the -debug
flag stopped crashing, but resulted in the text rendering very strangely.
The HaxePunk debug text is supposed to be white (on the edges of the screen), but it's black with white specks.
I think I had the same issue. It turned out that there weren't any fonts available on my android device. Adding one obviously solved it.
Just adding notes/ bumping this issue:
Specifically this crash occurs with Lime 2.9.1 / Openfl 3.6.1 (Haxe 3.2.1, though still happens with Haxe 3.3.0). Lime 2.9.0 / Openfl 3.6.0 display the text properly on Android.
As mentioned above, it only crashes when you both set text and addChild. If you do only one it doesn't crash. I tried setting up fonts to see if I could get around the issue, but no luck.
This problem seems fixed with lime 3.0.0 and openfl 4.0.0 (with haxe 3.3.02).
I can't upgrade to that version, because my game relies so much on drawTiles. Is there any work around for this?
update : fixed by using lime and openfl from git
After compiling and installing this app on my Galaxy S3 it just crashes whenever I try to open the app. This started happening after I updated openfl today
class Main extends Sprite {
}