Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.84k stars 819 forks source link

Wrong textBounds for htmlText (Starling 2+) #913

Open vulkanosaure opened 7 years ago

vulkanosaure commented 7 years ago

Hi Daniel,

i found that when property isHtmlText is set to true, (wether or not html formatting is actually present), the textBounds property doesn't give the innerBounds of the textfield, but the general bounds (textfield size).

I don't have a simplified example, but i can provide one if needed.

cheers for the great work and excelent improvements of starling 2.0 !

PrimaryFeather commented 7 years ago

Thanks a lot for the report! I'll see what I can do about it. :smile:

PrimaryFeather commented 7 years ago

Unfortunately, there is no quick fix for this. I just tried to write an explanation, but ... it's complicated. :wink:

The reason has to do with alignment: with HTML text, you can specify a different alignment in the HTML code than in the actual TextField. To work around this, I'm simply using the complete width of the TextField as the "Canvas" to draw the text into, whereas non-HTML text is moved manually to the left or right. And that's what you're seeing (the full-size canvas).

Long story short, it would require some big changes in the TrueTypeCompositor, and that's a class that required a lot of trial and error to get it to work as it should. The TextField is quite a beast. :shit:

The only workaround I can offer right now is to create a duplicate, invisible flash.text.TextField with the same settings, and calculate the text bounds like this:

private function getTextBounds(textField:TextField, out:Rectangle=null):Rectangle
{
    if (out == null) out = new Rectangle();
    else             out.setEmpty();

    var i:int;
    var lineMetrics:TextLineMetrics;
    var numLines:int = textField.numLines;

    if (numLines > 0)
    {
        var height:Number = 0;
        var left:Number = textField.width;
        var right:Number = 0;

        for (i=0; i<numLines; ++i)
        {
            lineMetrics = textField.getLineMetrics(i);

            if (lineMetrics.width > 0 && lineMetrics.height > 0)
            {
                if (left > lineMetrics.x)
                    left = lineMetrics.x;
                if (right < lineMetrics.x + lineMetrics.width)
                    right = lineMetrics.x + lineMetrics.width;

                height += lineMetrics.height;
            }
        }

        out.setTo(left, 2, right - left, height - lineMetrics.leading);
    }

    return out;
}

You can then use this information for the horizontal text bounds. The vertical data you get from the Starling text field is correct.

Does that ease your pain? :wink:

vulkanosaure commented 7 years ago

ok, i thanks, i could make that working yeah, i can imagine the complexity of the work around text and that messing around with that is not necessary worthwhile. Thanks for your work-around, that will do it for me ;)

PrimaryFeather commented 7 years ago

Thanks a lot for your understanding! Just to make this clear: this does need fixing, but I need to give this some time, and you probably can't wait for that — so you're better off with that workaround. :smile:

Cheers!