Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filltext() canvas text position discrepencies between browsers

As can be seen in the screenshots at the bottom of the question or by going directly to the game. text is placed differently dependent on browser (firefox 15.0.1 renders differently then IE 9.9 and Chrome 21). call to draw function:

context.fillText(this.wlines[i], this.xcoord, this.ycoord + y + (t) * this.sizey);

constructor of object:

function textItem(text, xcoord, ycoord, sizex, sizey,style, context) {
this.wlines = [];
this.text = text;
this.xcoord = xcoord;
this.ycoord = ycoord;
this.sizex = sizex;
this.sizey = sizey;
this.style = style;

if (text == null) {
    text = "";
}
var lines = text.split("~");
// this is first line text
context.save();
if (this.style < 3) {
    context.shadowOffsetY = 2;
    context.font = 'bold 18px "palatino linotype"';
} else if (this.style == 4) {
    this.font = '16px "palatino linotype"';
    this.shadowOffsetX = 2;
    this.shadowOffsetY = 1;
    this.shadowColor = "rgba(255,255,255,1)";
}
if (this.style == 5) {
    this.wlines.push(text);
} else {
    for (j = 0; j < lines.length; j += 1) {
        var words = lines[j].split(" ");
        var lastLine = "";
        var l = sizex;
        var measure = 0;
        for (i = 0; i < words.length; i += 1) {
            var w = words[i];
            measure = context.measureText(lastLine + w).width;
            if (measure < l) {
                lastLine += (w + " ");
            } else {
                //this is body text
                if (this.style == 6) {
                    lastLine += "...";
                }
                this.wlines.push(lastLine);
                lastLine = (w + " ");
                if (this.style < 3) {
                    context.font = 'bold 14px "palatino linotype"';
                }
            }
            if (i == words.length - 1) {
                this.wlines.push(lastLine);
                break;
            }
        }
    }
}
context.restore();
}

text,xcoorc,ycoord,xsize,ysize are parsed from an xml file. The compond name in this example:

<sizex>196</sizex>
<sizey>20</sizey>
<xcoord>383</xcoord>
<ycoord>14</ycoord>

style is a defined value based on the text effects desired and context is the 2d context of the canvas to draw on (for layering effects).

As shown all values are exactly the same between browsers. The only check I do between browsers is

<meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1"/>

in the header of the html page.

I really don't know where the line height discrepancy is coming from and any help on the matter would be appreciated.

The line height discrepancy changes depending on the text but not in a manner that I have figured out yet. If there is any information that I have omitted please don't hesitate to ask. ff: ff screen http://www.sunshinecompound.com/images/firefoxscreen.png Chrome: chrome screen http://www.sunshinecompound.com/images/googlescreen.png

Update The solution for my program at least was to build use an offset. Further I got huge performance boosts by creating the text object and then saving the text object as an image. In FF which was the browser with the greatest slowdown I saw a little bit over a 5X decrease in overall program run-time. This is despite having to recreate the text object each time text dynamically changed in the program (I change dynamic counters per second and mouse hover effects every 200ms but with the performance I'm currently getting I can probably improve that to 100ms).

like image 768
Tyler Avatar asked Sep 25 '12 22:09

Tyler


1 Answers

Yep.

It's placed differently, scaled differently, kerned differently, aliased differently and even measured differently (as in measureText) between browsers.

If you need pixel consistency for your game then you're going to have to use images instead of text. Sorry. :(

The only way to make measureText consistent is to pre-compute.

The only way to make fillText consistent is to use images instead of text. It's must faster, anyway.

Both of these are untenable if the text is extremely dynamic, but if you only ever write say, less than 100 different pieces of text in your app, images are probably your best bet.

Otherwise, you could use a pixel font generated from an image (use drawImage with each letter or common word) and hope for OK performance, caching the longer, common strings.

like image 52
Simon Sarris Avatar answered Sep 21 '22 01:09

Simon Sarris