A character's width is the number of columns a terminal emulator uses to display its glyph. This width may vary with the combination of character, terminal emulator and font set. For a given combination, the width does not seem to vary with font size, weight, emphasis or underlining. That is, if the terminal emulator has sized its grid cells for a 12 point font, increasing the font size (and all grid cells) to accomodate an 18 or 40 point font does not seem to change the number of columns the character occupies.
In order to measure a character's width, the bash shell script
below puts the cursor in the home position, outputs a character, and then asks
the terminal emulator for the new cursor position using terminfo's
User string #7 (this string is often \033[6n). The terminal
emulator then injects the cursor position into the stdin input stream from
which it is read and used to determine the character's width.
And so the script does for each character from 0 through 0x10ffff, writing each character's width to a file named $TERM-character-width. The width will be a number from zero through four, or "exception" if the cursor moved unexpectedly. Often about 90 percent of characters will have a width of one column, with most of the rest being two.
#!/bin/bash
output_file=${TERM}-character-width
echo -n "" > ${output_file}
home=`infocmp -1 -l|grep "\shome="|sed "s/.*home=\(.*\),.*/\\1/"|sed "s/^\\\\[Ee]/\\\\033/"`
request=`infocmp -1 -l|grep "\su7="|sed "s/.*u7=\(.*\),.*/\\1/"|sed "s/^\\\\[Ee]/\\\\033/"`
trap "stty echo" EXIT; stty -echo
for i in {0..1114111}; do
printf -v hex "%06x" $i
echo -e "${home}_\U${hex}_${request} "
if [ $((${i} % 1000)) -eq 0 ]; then
clear; echo -e "\n\n\nAbout "$(($((1114111-${i}))/11141))" percent remaining "
fi
read -d R response
response=${response##*[}
column=${response##*;}
line=${response%%;*}
width=$((${column}-3))
if [ x${line} != x1 -o ${width} -lt 0 -o ${width} -gt 4 ]; then
width=exception
fi
echo ${hex},${width} >> ${output_file}
done
I dedicate this script to the public domain.