Bash function to generate colored output
Three things strike me immediately:


You are treating foreground and background colors equally, and giving preference to reverse video and underline(?). Why is red foreground %fRed% while reverse video is %r%? Aren't you more likely to use red,yellow,green foreground than reverse video? Aren't you more likely to use foreground colors than background colors?

I think you should give some thought to the "Huffmanization" of your color names. Maybe you need %r% %g% %y% as shortcuts for foreground red, green, and yellow. (Or, maybe not. It depends on what your use case is going to be. If you're writing a rogue-like in bash, maybe you have a different color vocabulary...)

I would suggest that foreground colors just be color names, while background colors have a bg prefix:  %cyan% versus %bgCyan% for example. This makes background colors more expensive than they currently are (1 extra character) but makes foreground colors less expensive, and I suspect they'll be more common.
Next, I think you're doing too much work inside your loop. You are actually processing the format string character-by-character! Given that the beginning delimiter and ending delimiter are the same - % - you could use IFS to split the string into an array and process the segments of the array. Given a string like "before % during % after", or even "%during%", you know that the alternate members of the array are going to be tags: even indices text, odd indices tag.

See this answer on SO for how to split a string.

This would make change your loop from processing characters into processing "strings", and should speed up your function.
Finally, there are a lot of "magic strings" in your code. Like magic numbers, you should replace these with constants (variables) and reference them just once. In particular, I'm thinking of ${pfx} ("\033[") and maybe ${reset} ("${pfx}0m").