Text color possible bug (textColor property - set via Text.setTextProperty() - is ignored)


(TheCatProblem) #1

It appears that the textColor property of a Text class instance’s TextField (set using the setTextProperty method of the Text class) is ignored when the text is rendered.

It’s possible to change the color of the text by changing the color property of the Text instance, but doing so affects the background color of the TextField (if a background color is being used) since Text.color is the tint color property inherited from the Image class (it gets multiplied in).

Examples:

Text will be the desired color, but the background color will be multiplied by text.color:

text.color = 0xD5D5D5; // Text will be grey
text.setTextProperty("background", true);
text.setTextProperty("backgroundColor", 0xFF0000);

Text will be white; the background color will be the desired color:

worldText.setTextProperty("textColor", 0x0xD5D5D5); // No effect
worldText.setTextProperty("background", true);
worldText.setTextProperty("backgroundColor", 0xFF0000);

Is there a way to change the text color without affecting background color? Any suggestions would be appreciated!


(TheCatProblem) #2

I’m hesitant to reply to my own post, but I’m curious: has anyone been able to reproduce this behaviour?

For now, I’ve worked around it by stretching a tinted image of a 1x1 white pixel to match the size of the text field (instead of using the backgroundColor property), but it would be nice it there was a way to change the text color directly rather than having to change the tint color of the text object (which affects the background color), particularly now that the setTextProperty function is available.


(Brad Davies) #3

The reason worldText.setTextProperty(“textColor”,0xFFFF00) does not work is because the Text class only takes notice of the font, size, align, wordWrap, resizable, width & height properties.

I will dig into the Text class a little more and see if I can find a solution for you, as I am also interested in a solution. :slight_smile:

EDIT: Apologies, seems my original reasoning was wrong after checking the source code. What you are saying seems correct, most of the normal TextFormat and TextField parameters work fine, but the color is handled differently (due to Text inheriting from Image). Exactly why the Text class uses a colortransform with tinting, rather than just the textColor property, I do not know. I will try looking for a better workaround.


(Brad Davies) #4

BOOM! Workaround found!

This works like you would expect;

var txt:Text = new Text("OH MY IT WORKS! But wait, there's more!");
txt.setTextProperty("background",true);
txt.setTextProperty("backgroundColor",0xFF0000); //Nice and red
txt.color = 0x00FF00; //Nice and green
txt.richText = "Green text on red background!";

(TheCatProblem) #5

Excellent - thanks for figuring this out, DPbrad. Looking at Text.as, I see that setting the richText property prevents the updateColorTransform method inherited from Image from being called and thus avoids the tinting problem.

It might be useful if this was mentioned in the documentation for the Text class (assuming the underlying behaviour isn’t modified), as the relatively recent addition of the setTextProperty function could result in a number of developers trying to change the background color of a Text instance’s associated TextField.


(Zachary Lewis) #6

The documentation addition and problem solution you’ve posted would be great to add to the library’s issues list!


(TheCatProblem) #7

I’ve opened an issue suggesting that the documentation for Text be updated to include this information.


(Draknek) #8

This is a weird enough edge-case that I don’t feel documenting it makes sense: it’s information that’s just going to be irrelevant/confusing to almost everyone.

The setTextProperty() method should come with a warning that it’s kinda a hack maybe :stuck_out_tongue:

We can detect if _field.background is true and behave differently, but that’s not the only code change to consider: I don’t know how setTextProperty("opaqueBackground") will behave, and probably setTextProperty("textColor") shouldn’t be ignored?


(TheCatProblem) #9

I’m not sure that this constitutes an edge-case; text boxes frequently incorporate a background color and implementing that by setting a property is simpler than maintaining a separate background object (which may have to change its dimensions or position every time its associated text box is updated). FP’s Graphiclist class makes the latter implementation easier than it would otherwise be, but the presence of setTextProperty makes it rather tempting to try setting TextField.backgroundColor instead.

I suppose a warning that properties set using setTextProperty may be ignored or produce unexpected results (as in the tinted background case) would suffice, although this seems to call into question the utility of setTextProperty.


(Zachary Lewis) #10

Most of the text boxes I’ve seen (in text-heavy games like RPGs) use custom graphics or borders as a background and change the colors of specific words (like character names and key locations), not the entire text.


(bnnorman) #11

I bashed my head against the Text brickwall for days until I found this. Thank you Brad. As a result I wrote this extension to Text. Most of the time people just want to chuck some coloured text at X,Y with or without a background without writing 4 lines of code each time.

package utils { import net.flashpunk.graphics.Text; /** * … * @author Brian * * Fixes text tinting problem. * * Obtained from Brad Davies workaround here. * Text color possible bug (textColor property - set via Text.setTextProperty() - is ignored) */ public class SimpleText extends Text {

    public function SimpleText(Txt:String, x:Number,y:Number,fontSize:Number=12,txtColor:Number=0xFFFFFF,bgColor:Number=NaN) 
    {
        super("If you can see this I failed you!!", x, y,{size: fontSize});

        if (isNaN(bgColor))
        {
            this.setTextProperty("background",false);
        }
        else 
        {
            this.setTextProperty("background",true);
            this.setTextProperty("backgroundColor", bgColor);
        }
        this.color = txtColor
        this.richText = Txt;

    }
}

}


(bnnorman) #12

After some further tuning I offer this improved version of my SImpleText. (Also getting the hang of this BBCODE thing.)

package utils 
{
    import net.flashpunk.graphics.Text;
    
    // my color definitions obtained from http://www.w3schools.com/tags/ref_color_tryit.asp?hex=F0F8FF
    import Const.color;                    
    
    /**
     * ...
     * @author Brian
     * 
     * Fixes text tinting problem.
     * 
     * Idea developed from Brad Davies workaround here.
     * http://developers.useflashpunk.net/t/text-color-possible-bug-textcolor-property-set-via-text-settextproperty-is-ignored/550/8
     * 
     * 
     * 27/8/14 
     * Code changed to use an options parameter instead of explicit color/bgcolor parameters.
     * Background box was bigger than the text - fixed, now fits.
     * 
     */
    public class SimpleText extends Text
    {
        
        // set your own defaults here
         private const DefTextSize:Number = 12;
         private const DefTextColor:Number = Const.color.White;

         /**
         * 
         * @param    Txt            text to display
         * @param    x            where
         * @param    y            where
         * @param    options        an optional object defining Text properties to set
         */
    
        public function SimpleText(Txt:String, x:Number,y:Number,options:Object=null) 
        {
            var bgcolor:uint=DefTextColor;
            var hasBackground:Boolean = false;
            
            if (options)
            {
                // store and delete any workaround properties
                if (options.hasOwnProperty("bgcolor"))
                    {                
                        hasBackground = true;
                        bgcolor = options.bgcolor;
                        delete options.bgcolor;
                    }

                }
                
            // create the underlying Text object
            super("", x, y, options);
            
            // the tinting workaround
            this.setTextProperty("background", hasBackground);
            if (hasBackground)    { this.setTextProperty("backgroundColor",bgcolor);    }
    
            // finally set the text as richText
            this.color = options.hasOwnProperty("color")?options.color:DefTextColor;
            this.richText = Txt;
        }
    }
        
}