Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by mkreitler

Hey all,

I just ran into this problem today and thought I'd share a possible solution.

The symptom: your font displays the wrong characters, usually past what you expect and sometimes printing more characters than it should.

The cause: for some reason, you'll get non-zero alpha values in the spaces between the bottom row of pixels in the font's bitmap. Since Impact uses this line to compute character spacings, the screws up the spacings.

The catch: this doesn't happen on all machines! With the same font, I ran fine on my iMac at work, but not on my Mac mini at home or a MacBook in the office. Who knows, maybe it's browser-dependent, too (though I was using Chrome in all cases).

One solution: modify the Impact code to look for alpha values below a threshold, rather than strictly zero.

In font.js:

_loadMetrics: function( image ) {
		// Draw the bottommost line of this font image into an offscreen canvas
		// and analyze it pixel by pixel.
		// A run of non-transparent pixels represents a character and its width
		
		this.height = image.height-1;
		this.widthMap = [];
		this.indices = [];
		
		var canvas = ig.$new('canvas');
		canvas.width = image.width;
		canvas.height = image.height;
		var ctx = canvas.getContext('2d');
		ctx.drawImage( image, 0, 0 );
		var px = ctx.getImageData(0, image.height-1, image.width, 1);
		
		var currentChar = 0;
		var currentWidth = 0;
		for( var x = 0; x < image.width; x++ ) {
			var index = x * 4 + 3; // alpha component of this pixel

// CHANGES IN HERE ------------------------------------------------------------------------
			if( px.data[index] > ig.Font.ALPHA_THRESHOLD ) {
				currentWidth++;
			}
			else if( px.data[index] <= ig.Font.ALPHA_THRESHOLD && currentWidth ) {
				this.widthMap.push( currentWidth );
				this.indices.push( x-currentWidth );
				currentChar++;
				currentWidth = 0;
			}
// END CHANGES -------------------------------------------------------------------------------
		}
		this.widthMap.push( currentWidth );
		this.indices.push( x-currentWidth );
	}
});

// ANOTHER CHANGE ------------------------------------------------------------------------
ig.Font.ALPHA_THRESHOLD = 2;
// END CHANGE ---------------------------------------------------------------------------------


Generally, I don't like messing with engine code, but this is fairly safe.

1 decade ago by Joncom

I wonder if you could run into this problem if you just used the font-tool? I did my font by hand yesterday and it seems to work ok. Glad you figured out a solution in any case.

1 decade ago by mkreitler

That's a good question, Joncom.

I should've tried re-touching the font data -- that's probably better than editing the engine code. I did examine the font in Gimp, and it looked like there was no data in the empty spaces (eyedropper couldn't pick up a color).

The fact that the same font gives me different results on different machines suggests there's something strange with the way the data is being encoded / decoded, and I know that recent iOS updates have introduced a bug where the bottom row of pixels in a png8 isn't correctly decoded. Even though I wasn't running on an iDevice, I'm now suspect of all PNG8 encoding under MacOS.

1 decade ago by MDChristie

I just came across the same issue, I generated a different font and it worked fine, maybe this is caused by fonts with particularly long descender interfering with the lines along the bottom?

1 decade ago by inkajoo

I can't thank you enough for tracking this down and posting the fix. This solved the mysterious text bug for our game in a jiffy.

Off the cuff I assume that the reason this happens is the browser automatically scales source images down if needed to optimize them for graphics cards with texture size limits. Likely using a filter to keep them from looking all pixel-y - thus, the tidy letter gaps become blurred.

1 decade ago by dmen

Didn't work for me. Seems to be an issue with large fonts from what I have seen. I just went through my current font image and made sure all the in between pixels were 0% alpha and it didn't help at all. I'm using a 128pt Arial Black - the image is 4332x96
If I simply do this:
this.font.draw("C", 625, 273);
I get a 'M' drawn instead.

Trying 72 point I get similar results.

At 60 point or below it works ok.

Really need larger fonts though.
Page 1 of 1
« first « previous next › last »