Skip to content

gui/tiletypes: remove COLOR_RESET use with Pen - #1604

Open
ChrisJohnsen wants to merge 1 commit into
DFHack:masterfrom
ChrisJohnsen:cj/gui-tiletypes-COLOR_RESET
Open

ChrisJohnsen wants to merge 1 commit into
DFHack:masterfrom
ChrisJohnsen:cj/gui-tiletypes-COLOR_RESET

Conversation

@ChrisJohnsen

Copy link
Copy Markdown
Contributor

Ref DFHack/dfhack#5864

This Pen use of COLOR_RESET as a foreground color never actually caused any OOB reads (before DFHack/dfhack#5864) since the foreground value already had masking applied to it (related to bold handling).

The EMPTY_LABEL is used to fill (with space characters) the blank portions of the gui/tiletypes "more options" entries that are not text label nor checkbox. Since spaces usually don't have any foreground pixels, the foreground used here mostly doesn't matter.

To prevent a visual change for fonts that have foreground pixels in the space character, the foreground should be COLOR_WHITE since this is equivalent to what happens when a COLOR_RESET foreground is specified. Luckily, UI_COLORS.HIGHLIGHTED (used for the text portion of the entry while in the hover state) is also COLOR_WHITE.

Suggestion: Switch to specifying hpen=UI_COLORS.HIGHLIGHTED. This matches the text portion of the options and produces an effective Pen that is unchanged from when COLOR_RESET was used. Thus, there are no visible changes.

Pictured here:
The (top of the) "more options" window of gui/tiletypes with mouse hovering over the "Light" entry. This shows the COLOR_WHITE text under the mouse and the COLOR_GREY text for the non-hover entries. The bottom row shows what happens if the background of EMPTY_TOKEN is COLOR_WHITE instead of COLOR_BLACK.

gui/tiletypes more options

COLOR_RESET should not be used with Pen.

The original COLOR_RESET `fg` value here ended up being treated as
COLOR_WHITE: for a Pen specified with just a single number, both
COLORS_RESET (-1) and COLOR_WHITE (15) are decoded as "bold"
grey-on-black (7-on-0) due to the masking done when decoding the Pen.

The EMPTY_TOKEN is used to draw the "blank space" (non-text/non-checkbox
parts) of the "more options" entries. Use of the `hpen` field overrides
label text's normal "swap foreground and background" hover effect.

Use UI_COLORS.HIGHLIGHTED to match the hover styling of the left side
(text label) of the option entries (`OptionsPopup:init` `addOption`
`left_specs` `pens_hover`). Since only a foreground color is specified
for both the "left text" and the EMPTY_TOKEN, they both use Pen's
default background color: black.

Nicely, UI_COLORS.HIGHLIGHTED *is* COLOR_WHITE, so there isn't a visual
change even if the active font has foreground pixels in its space
characters (EMPTY_TOKEN is always drawn as space characters).
@ab9rf

ab9rf commented Sep 22, 2026

Copy link
Copy Markdown
Member

Needs changelog

@ChrisJohnsen

Copy link
Copy Markdown
Contributor Author

To be clear, there is no user-visible change in behavior or appearance after the change in this PR. The code change here is just to get rid of a "bad example" of using COLOR_RESET as a Pen color.

Do you still want a changelog?

I just re-tested this by patching a copy of 53.16-r2rc1 downloaded from Steam (which includes DFHack/dfhack#5910). I also used a "visible space" font (modified from the default font to include foreground pixels in the space character) to make sure there was no behavior change even in that edge case.

Both before and after the change in this PR, the relevant UI looks like the top half of the image.
The bottom half of the image uses an separate EMPTY_TOKEN value (not the original value, and not the one from this PR) that was selected to make visible the usually invisible use of the hpen in EMPTY_TOKEN. In other words, it show where to look to verify that the code changes in this PR are not actually making any visible changes.


BTW, the the original COLOR_RESET usage in this code is not actually affected by the changes in 5910 since that only touched decode_pen (decoding a Lua table to a Pen instance). The "number only" usage here never uses decode_pen; it is handled in CheckPen where the number is simply masked off and used as the foreground color of a fresh Pen instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants