With all the drawing tools in the TeX ecosystem, it is tempting to use them to draw new symbols. While there are several approaches to make them scale well with the surrounding text, choosing a stroke width, which will blend in, is much trickier.
For a math font, I'd use the thickness of the fraction bar as an approximation. But for text fonts, the only approach I can think of is to test for the current font and then look up some value in a manually curated look-up table. Here a quick sketch for just 3 different fonts:
```
\documentclass{article}
\usepackage{tgbonum}
\usepackage{tikz}
\newlength{\Iheight}
\newlength{\stroke}
\ExplSyntaxOn
\makeatletter
\newcommand{\quack}{%
\setlength{\Iheight}{\fontcharht\font`I}%
\str_case_e:nnF { \f@family }{
{qbk} { \dim_set:Nn \stroke { 0.12\Iheight } }
{bch} { \dim_set:Nn \stroke { 0.1\Iheight } }
% ....
}{
\dim_set:Nn \stroke { 0.06\Iheight }
}
\begin{tikzpicture}[baseline]
\draw[line~width=\stroke] (0,0) -- (\Iheight,\Iheight)
(0,\Iheight) -- (\Iheight,0);
\end{tikzpicture}~
}
\makeatother
\ExplSyntaxOff
\begin{document}
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{bch}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{cmr}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\end{document}
```

Given the number of fonts, families etc. this will get out of hand very quickly. Is there any other property I could use as an approximation? It wouldn't have to be perfect or work in all cases, but just to reduce the number of cases I would have to deal with manually?
**Update:**
the approach below has been bundled into the package [`BusyPanda`](https://ctan.org/pkg/panda)
```
\documentclass[varwidth,border=1pt]{standalone}
\usepackage{BusyPanda}
\newcommand{\bamboo}{%
\rule{\BusyPanda{0.125}\fontcharht\font`I}{\fontcharht\font`I}
}
\begin{document}
normal cmr: \bamboo
\bfseries
bold cmr: \bamboo
\normalfont
\fontfamily{cmbr}\selectfont
normal cmbr: \bamboo
\bfseries
bold cmbr: \bamboo
\end{document}
```

----
Different approach:
I wrote a quick [root script](https://root.cern/) to compile a test document with each font, convert it into an image and then calculate the fraction of the image, which is filled with ink. This fraction can then be used as a rough approximation of the heaviness.
Root script `MeassureInk.C`:
```cpp
#include <iostream>
#include <sstream>
#include "TASImage.h"
#include "TSystem.h"
void MeassureInk(){
const int size = 152;
double fraction[size];
int w,h;
TASImage* im;
string font[size] = {"cmr", "cmdh", "cmss", "cmtt", "cmvtt", "cmbr", "ccr", "clm", "clmd", "clms", "clmqs", "clmv", "clmt", "uaq", "pbk", "ptm", "ppl", "pnc", "pag", "phv", "pcr", "pzc", "ugq", "ugm", "ua1", "ulg", "uop", "zgmx", "qag", "qbk", "qcr", "qcs", "qhv", "qhvc", "qpl", "qtm", "qzc", "put", "Heuristica-TLF", "erewhon-OsF", "bch", "jkp", "jkpl", "jkpx", "jkp", "jkpss", "jkpss", "jkptt", "Alegreya-OsF", "Alegreya-TLF", "AlegreyaSans-OsF", "AmiciLogo", "AnonymousPro", "antp", "antt", "anttc", "anttl", "anttlc", "AccanthisADFStdNoThree-LF", "ybd", "ybv", "yes", "GilliusADF-LF", "GilliusADFNoTwo-LF", "yly", "MintSpirit-LF", "yrd", "UniversalisADFStd-LF", "yvt", "yv2", "yv1", "yv3", "yvtd", "yv1d", "yvo", "yvod", "auncl", "augie", "AuriocusKalligraphicus", "fav", "fve", "fvs", "fvm", "sqrc", "DejaVuSerif-TLF", "DejaVuSans-TLF", "DejaVuSansMono-TLF", "Cabin-TLF", "Caladea-TLF", "cantarell-OsF", "Crlt-TLF", "cmin", "Cinzel-LF", "CinzelDecorative-LF", "ClearSans-TLF", "comfortaa", "cyklop", "droidserif", "droidsans", "droidsansmono", "EBGaramond-OsF", "fbb-LF", "FiraSans-TLF", "frc", "gentium", "artemisia", "bodoni", "udidot", "neohellenic", "zi4", "iwona", "iwonac", "iwonal", "iwonalc", "JanaSkrivana", "kurier", "kurierc", "kurierl", "kurierlc", "lato-OsF", "LibreBskvl-LF", "LibreCsln-TLF", "LinuxLibertineT-OsF", "LinuxLibertineDisplayT-OsF", "LinuxBiolinumT-OsF", "LinuxLibertineMonoT-TLF", "Lbstr-LF", "LukasSvatba", "ul9", "Merriwthr-OsF", "MerriwthrSans-TLF", "nanummj", "nanumgt", "opensans-TLF", "Ovrlck-LF", "Ovrlck-LF", "PlyfrDisplay-OsF", "PTSerif-TLF", "PTSerifCaption-TLF", "PTSans-TLF", "PTSansNarrow-TLF", "PTSansCaption-TLF", "PTMono-TLF", "Quattro-LF", "QuattroSans-LF", "Raleway-TLF", "Roboto-TLF", "RobotoSlab-TLF", "SourceCodePro-TLF", "SourceSansPro-TLF", "stix", "yfrak"};
for (int i = 0; i < size; i++) {
std::cout << font[i] << std::endl;
// generating sample png
std::ostringstream cmd;
cmd << "pdflatex --interaction=batchmode '\\def\\quack{" << font[i] << "}\\input{fonttest.tex}'";
gSystem->Exec(cmd.str().c_str());
gSystem->Exec("pdftocairo -png -r 1000 -singlefile fonttest.pdf fonttest");
// open image
im = (TASImage*) TASImage::Open("fonttest.png");
w = im->GetWidth();
h = im->GetHeight();
UInt_t* arr = im->GetArgbArray();
double A[w*h], r[w*h], g[w*h], b[w*h], step[w*h];
fraction[i] = 0.0;
// read rgb values of each pixel
for (int j=0;j<w*h;j++){
UInt_t val = arr[j];
A[j] = (UInt_t)((val >> 24) & 0xFF);
r[j] = (UInt_t)((val >> 16) & 0xFF);
g[j] = (UInt_t)((val >> 8) & 0xFF);
b[j] = (UInt_t)((val ) & 0xFF);
fraction[i] = fraction[i] + (255.0-r[j])/255.0;
}
// normalise to image size
fraction[i] = fraction[i]/(w*h);
std::cout << font[i] << ": " << fraction[i] << std::endl;
}
}
```
`fonttest.tex`
```
\documentclass{standalone}
\usepackage[B1,LY1,T1]{fontenc}
\usepackage{aurical}
\begin{document}
\fontfamily{\quack}%
\selectfont
The quick brown fox jumped over the lazy dog
\end{document}
```
----
A test document using the calculated factors:
```
\documentclass[varwidth,border=5pt]{standalone}
\usepackage[B1,LY1,T1]{fontenc}
\usepackage{aurical}
\usepackage{tikz}
\newlength{\Iheight}
\newlength{\fudgefactor}
\newlength{\stroke}
\ExplSyntaxOn
\makeatletter
\newcommand{\getStrokeWD}{
\dim_set:Nn \fudgefactor {.6\fontcharht\font`I}
\dim_set:Nn \stroke {
\str_case_e:nnF {\f@family} {
{cmr}{0.143705\fudgefactor}
{cmdh}{0.117034\fudgefactor}
{cmss}{0.167922\fudgefactor}
{cmtt}{0.165045\fudgefactor}
{cmvtt}{0.181806\fudgefactor}
{cmbr}{0.149451\fudgefactor}
{ccr}{0.182321\fudgefactor}
{clm}{0.137929\fudgefactor}
{clmd}{0.114286\fudgefactor}
{clms}{0.168069\fudgefactor}
{clmqs}{0.17049\fudgefactor}
{clmv}{0.180846\fudgefactor}
{clmt}{0.162863\fudgefactor}
{uaq}{0.190493\fudgefactor}
{pbk}{0.178257\fudgefactor}
{ptm}{0.179608\fudgefactor}
{ppl}{0.160638\fudgefactor}
{pnc}{0.198033\fudgefactor}
{pag}{0.184161\fudgefactor}
{phv}{0.209548\fudgefactor}
{pcr}{0.101976\fudgefactor}
{pzc}{0.147542\fudgefactor}
{ugq}{0.346545\fudgefactor}
{ugm}{0.148205\fudgefactor}
{ua1}{0.209476\fudgefactor}
{ulg}{0.172151\fudgefactor}
{uop}{0.164666\fudgefactor}
{zgmx}{0.147344\fudgefactor}
{qag}{0.181006\fudgefactor}
{qbk}{0.183262\fudgefactor}
{qcr}{0.10322\fudgefactor}
{qcs}{0.19776\fudgefactor}
{qhv}{0.207783\fudgefactor}
{qhvc}{0.217407\fudgefactor}
{qpl}{0.162816\fudgefactor}
{qtm}{0.181038\fudgefactor}
{qzc}{0.164399\fudgefactor}
{put}{0.18489\fudgefactor}
{Heuristica-TLF}{0.187581\fudgefactor}
{erewhon-OsF}{0.187347\fudgefactor}
{bch}{0.180547\fudgefactor}
{jkp}{0.159545\fudgefactor}
{jkpl}{0.131157\fudgefactor}
{jkpx}{0.159545\fudgefactor}
{jkp}{0.159545\fudgefactor}
{jkpss}{0.170264\fudgefactor}
{jkpss}{0.170264\fudgefactor}
{jkptt}{0.14255\fudgefactor}
{Alegreya-OsF}{0.172776\fudgefactor}
{Alegreya-TLF}{0.17406\fudgefactor}
{AlegreyaSans-OsF}{0.184842\fudgefactor}
{AmiciLogo}{0.100721\fudgefactor}
{AnonymousPro}{0.150076\fudgefactor}
{antp}{0.173019\fudgefactor}
{antt}{0.178006\fudgefactor}
{anttc}{0.186403\fudgefactor}
{anttl}{0.145807\fudgefactor}
{anttlc}{0.152663\fudgefactor}
{AccanthisADFStdNoThree-LF}{0.140313\fudgefactor}
{ybd}{0.150686\fudgefactor}
{ybv}{0.162085\fudgefactor}
{yes}{0.130783\fudgefactor}
{GilliusADF-LF}{0.166004\fudgefactor}
{GilliusADFNoTwo-LF}{0.166213\fudgefactor}
{yly}{0.181598\fudgefactor}
{MintSpirit-LF}{0.171893\fudgefactor}
{yrd}{0.154166\fudgefactor}
{UniversalisADFStd-LF}{0.162126\fudgefactor}
{yvt}{0.164682\fudgefactor}
{yv2}{0.143755\fudgefactor}
{yv1}{0.157972\fudgefactor}
{yv3}{0.136458\fudgefactor}
{yvtd}{0.252267\fudgefactor}
{yv1d}{0.207436\fudgefactor}
{yvo}{0.157335\fudgefactor}
{yvod}{0.197548\fudgefactor}
{auncl}{0.172741\fudgefactor}
{augie}{0.172633\fudgefactor}
{AuriocusKalligraphicus}{0.121692\fudgefactor}
{fav}{0.197919\fudgefactor}
{fve}{0.187635\fudgefactor}
{fvs}{0.198942\fudgefactor}
{fvm}{0.170971\fudgefactor}
{sqrc}{0.264533\fudgefactor}
{DejaVuSerif-TLF}{0.186908\fudgefactor}
{DejaVuSans-TLF}{0.197323\fudgefactor}
{DejaVuSansMono-TLF}{0.167788\fudgefactor}
{Cabin-TLF}{0.205574\fudgefactor}
{Caladea-TLF}{0.188793\fudgefactor}
{cantarell-OsF}{0.17502\fudgefactor}
{Crlt-TLF}{0.206747\fudgefactor}
{cmin}{0.159805\fudgefactor}
{Cinzel-LF}{0.130158\fudgefactor}
{CinzelDecorative-LF}{0.138932\fudgefactor}
{ClearSans-TLF}{0.198669\fudgefactor}
{comfortaa}{0.16007\fudgefactor}
{cyklop}{0.328567\fudgefactor}
{droidserif}{0.196808\fudgefactor}
{droidsans}{0.196536\fudgefactor}
{droidsansmono}{0.160372\fudgefactor}
{EBGaramond-OsF}{0.147308\fudgefactor}
{fbb-LF}{0.134621\fudgefactor}
{FiraSans-TLF}{0.1985\fudgefactor}
{frc}{0.0804483\fudgefactor}
{gentium}{0.179608\fudgefactor}
{artemisia}{0.162076\fudgefactor}
{bodoni}{0.138769\fudgefactor}
{udidot}{0.15622\fudgefactor}
{neohellenic}{0.14328\fudgefactor}
{zi4}{0.156654\fudgefactor}
{iwona}{0.156578\fudgefactor}
{iwonac}{0.166489\fudgefactor}
{iwonal}{0.121128\fudgefactor}
{iwonalc}{0.127687\fudgefactor}
{JanaSkrivana}{0.102789\fudgefactor}
{kurier}{0.151921\fudgefactor}
{kurierc}{0.161325\fudgefactor}
{kurierl}{0.117323\fudgefactor}
{kurierlc}{0.123699\fudgefactor}
{lato-OsF}{0.203125\fudgefactor}
{LibreBskvl-LF}{0.175986\fudgefactor}
{LibreCsln-TLF}{0.172488\fudgefactor}
{LinuxLibertineT-OsF}{0.167461\fudgefactor}
{LinuxLibertineDisplayT-OsF}{0.142924\fudgefactor}
{LinuxBiolinumT-OsF}{0.164686\fudgefactor}
{LinuxLibertineMonoT-TLF}{0.141775\fudgefactor}
{Lbstr-LF}{0.243631\fudgefactor}
{LukasSvatba}{0.100165\fudgefactor}
{ul9}{0.178869\fudgefactor}
{Merriwthr-OsF}{0.20494\fudgefactor}
{MerriwthrSans-TLF}{0.230098\fudgefactor}
{nanummj}{0.117975\fudgefactor}
{nanumgt}{0.162379\fudgefactor}
{opensans-TLF}{0.180448\fudgefactor}
{Ovrlck-LF}{0.159994\fudgefactor}
{Ovrlck-LF}{0.159994\fudgefactor}
{PlyfrDisplay-OsF}{0.1756\fudgefactor}
{PTSerif-TLF}{0.195807\fudgefactor}
{PTSerifCaption-TLF}{0.210392\fudgefactor}
{PTSans-TLF}{0.191873\fudgefactor}
{PTSansNarrow-TLF}{0.2021\fudgefactor}
{PTSansCaption-TLF}{0.203523\fudgefactor}
{PTMono-TLF}{0.16183\fudgefactor}
{Quattro-LF}{0.145772\fudgefactor}
{QuattroSans-LF}{0.152473\fudgefactor}
{Raleway-TLF}{0.179608\fudgefactor}
{Roboto-TLF}{0.21017\fudgefactor}
{RobotoSlab-TLF}{0.214408\fudgefactor}
{SourceCodePro-TLF}{0.145125\fudgefactor}
{SourceSansPro-TLF}{0.18905\fudgefactor}
{stix}{0.181014\fudgefactor}
{yfrak}{0.183\fudgefactor}
}{0.15\fudgefactor}
}
% special cases for some bold fonts
\str_if_eq:VnT \f@series {b} {
\dim_set:Nn \stroke {
\str_case_e:nnF {\f@family} {
{cmr}{0.197865\fudgefactor}
{cmdh}{0.117034\fudgefactor}
{cmss}{0.245886\fudgefactor}
{cmtt}{0.165045\fudgefactor}
{cmvtt}{0.181806\fudgefactor}
{cmbr}{0.263226\fudgefactor}
{ccr}{0.197865\fudgefactor}
{clm}{0.193821\fudgefactor}
{clmd}{0.114286\fudgefactor}
{clms}{0.240529\fudgefactor}
{clmqs}{0.247783\fudgefactor}
{clmv}{0.221155\fudgefactor}
{clmt}{0.195427\fudgefactor}
{uaq}{0.190493\fudgefactor}
{pbk}{0.294787\fudgefactor}
{ptm}{0.259379\fudgefactor}
{ppl}{0.218724\fudgefactor}
{pnc}{0.269957\fudgefactor}
{pag}{0.286817\fudgefactor}
{phv}{0.29851\fudgefactor}
{pcr}{0.237097\fudgefactor}
{pzc}{0.147542\fudgefactor}
{ugq}{0.346545\fudgefactor}
{ugm}{0.192678\fudgefactor}
{ua1}{0.292673\fudgefactor}
{ulg}{0.172151\fudgefactor}
{uop}{0.247626\fudgefactor}
{zgmx}{0.198028\fudgefactor}
{qag}{0.290123\fudgefactor}
{qbk}{0.295368\fudgefactor}
{qcr}{0.229586\fudgefactor}
{qcs}{0.271563\fudgefactor}
{qhv}{0.297526\fudgefactor}
{qhvc}{0.298324\fudgefactor}
{qpl}{0.217954\fudgefactor}
{qtm}{0.261535\fudgefactor}
{qzc}{0.164399\fudgefactor}
{put}{0.266366\fudgefactor}
{Heuristica-TLF}{0.268307\fudgefactor}
{erewhon-OsF}{0.262209\fudgefactor}
{bch}{0.236802\fudgefactor}
{jkp}{0.211202\fudgefactor}
{jkpl}{0.178681\fudgefactor}
{jkpx}{0.211202\fudgefactor}
{jkp}{0.211202\fudgefactor}
{jkpss}{0.213081\fudgefactor}
{jkpss}{0.213081\fudgefactor}
{jkptt}{0.172506\fudgefactor}
{Alegreya-OsF}{0.261613\fudgefactor}
{Alegreya-TLF}{0.261613\fudgefactor}
{AlegreyaSans-OsF}{0.276886\fudgefactor}
{AmiciLogo}{0.150883\fudgefactor}
{AnonymousPro}{0.220943\fudgefactor}
{antp}{0.213749\fudgefactor}
{antt}{0.236086\fudgefactor}
{anttc}{0.241165\fudgefactor}
{anttl}{0.20662\fudgefactor}
{anttlc}{0.215365\fudgefactor}
{AccanthisADFStdNoThree-LF}{0.203997\fudgefactor}
{ybd}{0.196674\fudgefactor}
{ybv}{0.226247\fudgefactor}
{yes}{0.214362\fudgefactor}
{GilliusADF-LF}{0.217861\fudgefactor}
{GilliusADFNoTwo-LF}{0.219261\fudgefactor}
{yly}{0.219851\fudgefactor}
{MintSpirit-LF}{0.237611\fudgefactor}
{yrd}{0.190303\fudgefactor}
{UniversalisADFStd-LF}{0.22722\fudgefactor}
{yvt}{0.229559\fudgefactor}
{yv2}{0.202607\fudgefactor}
{yv1}{0.219529\fudgefactor}
{yv3}{0.189118\fudgefactor}
{yvtd}{0.252267\fudgefactor}
{yv1d}{0.240469\fudgefactor}
{yvo}{0.203535\fudgefactor}
{yvod}{0.197548\fudgefactor}
{auncl}{0.204576\fudgefactor}
{augie}{0.172633\fudgefactor}
{AuriocusKalligraphicus}{0.179447\fudgefactor}
{fav}{0.306534\fudgefactor}
{fve}{0.274408\fudgefactor}
{fvs}{0.306239\fudgefactor}
{fvm}{0.238433\fudgefactor}
{sqrc}{0.279584\fudgefactor}
{DejaVuSerif-TLF}{0.27131\fudgefactor}
{DejaVuSans-TLF}{0.29966\fudgefactor}
{DejaVuSansMono-TLF}{0.235061\fudgefactor}
{Cabin-TLF}{0.26225\fudgefactor}
{Caladea-TLF}{0.264705\fudgefactor}
{cantarell-OsF}{0.258705\fudgefactor}
{Crlt-TLF}{0.285776\fudgefactor}
{cmin}{0.131516\fudgefactor}
{Cinzel-LF}{0.226302\fudgefactor}
{CinzelDecorative-LF}{0.239315\fudgefactor}
{ClearSans-TLF}{0.279376\fudgefactor}
{comfortaa}{0.199374\fudgefactor}
{cyklop}{0.328567\fudgefactor}
{droidserif}{0.269543\fudgefactor}
{droidsans}{0.287283\fudgefactor}
{droidsansmono}{0.160372\fudgefactor}
{EBGaramond-OsF}{0.224536\fudgefactor}
{fbb-LF}{0.178493\fudgefactor}
{FiraSans-TLF}{0.305495\fudgefactor}
{frc}{0.0996681\fudgefactor}
{gentium}{0.179608\fudgefactor}
{artemisia}{0.217387\fudgefactor}
{bodoni}{0.186868\fudgefactor}
{udidot}{0.209602\fudgefactor}
{neohellenic}{0.220088\fudgefactor}
{zi4}{0.235073\fudgefactor}
{iwona}{0.208144\fudgefactor}
{iwonac}{0.22239\fudgefactor}
{iwonal}{0.185575\fudgefactor}
{iwonalc}{0.197149\fudgefactor}
{JanaSkrivana}{0.153915\fudgefactor}
{kurier}{0.201978\fudgefactor}
{kurierc}{0.215517\fudgefactor}
{kurierl}{0.179878\fudgefactor}
{kurierlc}{0.190939\fudgefactor}
{lato-OsF}{0.268036\fudgefactor}
{LibreBskvl-LF}{0.226337\fudgefactor}
{LibreCsln-TLF}{0.250349\fudgefactor}
{LinuxLibertineT-OsF}{0.2209\fudgefactor}
{LinuxLibertineDisplayT-OsF}{0.142924\fudgefactor}
{LinuxBiolinumT-OsF}{0.2225\fudgefactor}
{LinuxLibertineMonoT-TLF}{0.254554\fudgefactor}
{Lbstr-LF}{0.300155\fudgefactor}
{LukasSvatba}{0.150883\fudgefactor}
{ul9}{0.250776\fudgefactor}
{Merriwthr-OsF}{0.253363\fudgefactor}
{MerriwthrSans-TLF}{0.283978\fudgefactor}
{nanummj}{0.197005\fudgefactor}
{nanumgt}{0.240104\fudgefactor}
{opensans-TLF}{0.284816\fudgefactor}
{Ovrlck-LF}{0.224953\fudgefactor}
{Ovrlck-LF}{0.224953\fudgefactor}
{PlyfrDisplay-OsF}{0.259326\fudgefactor}
{PTSerif-TLF}{0.266027\fudgefactor}
{PTSerifCaption-TLF}{0.210392\fudgefactor}
{PTSans-TLF}{0.29164\fudgefactor}
{PTSansNarrow-TLF}{0.30885\fudgefactor}
{PTSansCaption-TLF}{0.283833\fudgefactor}
{PTMono-TLF}{0.249071\fudgefactor}
{Quattro-LF}{0.212042\fudgefactor}
{QuattroSans-LF}{0.217004\fudgefactor}
{Raleway-TLF}{0.179608\fudgefactor}
{Roboto-TLF}{0.301841\fudgefactor}
{RobotoSlab-TLF}{0.296934\fudgefactor}
{SourceCodePro-TLF}{0.237373\fudgefactor}
{SourceSansPro-TLF}{0.306746\fudgefactor}
{stix}{0.261034\fudgefactor}
{yfrak}{0.217662\fudgefactor}
}{\stroke}
}
}
}
\newcommand{\quack}{%
\dim_set:Nn \Iheight {\fontcharht\font`I}
\getStrokeWD
\begin{tikzpicture}[baseline]
\draw[line~width=\stroke] (0,0) -- (\Iheight,\Iheight)
(0,\Iheight) -- (\Iheight,0);
\end{tikzpicture}~
}
\newcommand{\currentfont}{\f@family}
\makeatother
\ExplSyntaxOff
\begin{document}
% list of fonts from https://tex.stackexchange.com/a/249140/36296
\foreach \macro in {
cmr, cmdh, cmss, cmtt, cmvtt, cmbr, ccr, clm, clmd, clms, clmqs, clmv, clmt, uaq, pbk, ptm, ppl, pnc, pag, phv, pcr, pzc, ugq, ugm, ua1, ulg, uop, zgmx, qag, qbk, qcr, qcs, qhv, qhvc, qpl, qtm, qzc, put, Heuristica-TLF, erewhon-OsF, bch, jkp, jkpl, jkpx, jkp, jkpss, jkpss, jkptt, Alegreya-OsF, Alegreya-TLF, AlegreyaSans-OsF, AmiciLogo, AnonymousPro, antp, antt, anttc, anttl, anttlc, AccanthisADFStdNoThree-LF, ybd, ybv, yes, GilliusADF-LF, GilliusADFNoTwo-LF, yly, MintSpirit-LF, yrd, UniversalisADFStd-LF, yvt, yv2, yv1, yv3, yvtd, yv1d, yvo, yvod, auncl, augie, AuriocusKalligraphicus, fav, fve, fvs, fvm, sqrc, DejaVuSerif-TLF, DejaVuSans-TLF, DejaVuSansMono-TLF, Cabin-TLF, Caladea-TLF, cantarell-OsF, Crlt-TLF, cmin, Cinzel-LF, CinzelDecorative-LF, ClearSans-TLF, comfortaa, cyklop, droidserif, droidsans, droidsansmono, EBGaramond-OsF, fbb-LF, FiraSans-TLF, frc, gentium, artemisia, bodoni, udidot, neohellenic, zi4, iwona, iwonac, iwonal, iwonalc, JanaSkrivana, kurier, kurierc, kurierl, kurierlc, lato-OsF, LibreBskvl-LF, LibreCsln-TLF, LinuxLibertineT-OsF, LinuxLibertineDisplayT-OsF, LinuxBiolinumT-OsF, LinuxLibertineMonoT-TLF, Lbstr-LF, LukasSvatba, ul9, Merriwthr-OsF, MerriwthrSans-TLF, nanummj, nanumgt, opensans-TLF, Ovrlck-LF, Ovrlck-LF, PlyfrDisplay-OsF, PTSerif-TLF, PTSerifCaption-TLF, PTSans-TLF, PTSansNarrow-TLF, PTSansCaption-TLF, PTMono-TLF, Quattro-LF, QuattroSans-LF, Raleway-TLF, Roboto-TLF, RobotoSlab-TLF, SourceCodePro-TLF, SourceSansPro-TLF, stix, yfrak%
}{
\normalfont
\fontfamily{\macro}
\selectfont
Nam dui ligula \quack Nam dui ligula (\currentfont)
\par
\bfseries
Nam dui ligula \quack Nam dui ligula (\currentfont)
\par
}
\end{document}
```
[](/image?hash=9ba1a054d957526eef059a4a9bc2d984a9d789cce56b14136e98680f1bd4802c)
(click in the image to see the full list)
**Update:**
the approach below has been bundled into the package [CleverPanda](https://ctan.org/pkg/panda)
```
\documentclass[varwidth,border=1pt]{standalone}
\usepackage{CleverPanda}
\newcommand{\bamboo}{%
\rule{\CleverPanda{}}{\fontcharht\font`I}
}
\begin{document}
normal cmr: \bamboo
\bfseries
bold cmr: \bamboo
\normalfont
\fontfamily{cmbr}\selectfont
normal cmbr: \bamboo
\bfseries
bold cmbr: \bamboo
\end{document}
```

---
This answer combines @Skillmon's great idea to utilise the height of the `.` with a manually curated list of exceptions (the list of test fonts was taken from the very useful answer https://tex.stackexchange.com/a/249140/36296):
```
\documentclass[varwidth]{standalone}
\usepackage[B1,LY1,T1]{fontenc}
\usepackage{aurical}
\usepackage{tikz}
\newlength{\Iheight}
\newlength{\dotheight}
\newlength{\stroke}
\ExplSyntaxOn
\makeatletter
\newcommand{\getStrokeWD}{
\dim_set:Nn \dotheight {\fontcharht\font`\.}
\dim_set:Nn \stroke {
\str_case_e:nnF {\f@family} {
{cmr}{0.5\dotheight}
{pcr}{0.3\dotheight}
{ugq}{1.0\dotheight}
{qag}{0.65\dotheight}
{qcr}{0.35\dotheight}
{pzc}{0.4\dotheight}
{put}{0.55\dotheight}
{Heuristica-TLF}{0.55\dotheight}
{jkpl}{0.4\dotheight}
{antt}{0.5\dotheight}
{anttc}{0.5\dotheight}
{anttl}{0.4\dotheight}
{anttlc}{0.4\dotheight}
{yes}{0.4\dotheight}
{UniversalisADFStd-LF}{0.8\dotheight}
{yvtd}{0.5\dotheight}
{yv1d}{0.5\dotheight}
{auncl}{0.25\dotheight}
{augie}{0.8\dotheight}
{fvm}{0.5\dotheight}
{sqrc}{0.2\dotheight}
{DejaVuSansMono-TLF}{0.5\dotheight}
{pbsi}{0.8\dotheight}
{cmin}{0.2\dotheight}
{cyklop}{1\dotheight}
{droidserif}{0.6\dotheight}
{droidsansmono}{0.5\dotheight}
{frc}{0.1\dotheight}
{Lbstr-LF}{0.7\dotheight}
{ul9}{0.6\dotheight}
{Merriwthr-OsF}{0.55\dotheight}
{MerriwthrSans-TLF}{0.55\dotheight}
{nanummj}{2\dotheight}
{nanumgt}{4\dotheight}
{SourceCodePro-TLF}{0.5\dotheight}
{Academy Engraved LET Plain:1.0(0)}{0.25\dotheight}
{American Typewriter Condensed Light(0)}{0.3\dotheight}
{American Typewriter Light(0)}{0.3\dotheight}
{BlackoakStd(0)}{1\dotheight}
{Clip(0)}{0.35\dotheight}
{Cochin Italic(0)}{.4\dotheight}
{Comic Sans MS(0)}{1\dotheight}
{Comic Sans MS Bold(0)}{1.5\dotheight}
{Courier New(0)}{0.3\dotheight}
{Cyklop-Regular(0)}{1\dotheight}
{Cyklop(0)}{1\dotheight}
{DulceChico(0)}{1\dotheight}
{Gill Sans UltraBold(0)}{1\dotheight}
{Gurmukhi MN Bold(0)}{0.8\dotheight}
{Hammerhead(0)}{0.8\dotheight}
{Hammerhead Black(0)}{1\dotheight}
{Heiti SC Light(0)}{0.3\dotheight}
{Heiti SC Medium(0)}{0.3\dotheight}
{Heiti TC Light(0)}{0.3\dotheight}
{Heiti TC Medium(0)}{0.3\dotheight}
{Impact(0)}{1.0\dotheight}
{JetBrains Mono NL Thin(0)}{0.3\dotheight}
{JetBrains Mono NL Thin Italic(0)}{0.3\dotheight}
{JetBrains Mono Thin(0)}{0.3\dotheight}
{JetBrains Mono Thin Italic(0)}{0.3\dotheight}
{Lao MN Bold(0)}{0.8\dotheight}
{Linux Biolinum Keyboard O(0)}{0.1\dotheight}
{Linux Libertine Capitals Semibold Italic(0)}{0.8\dotheight}
{Lithos Pro Black(0)}{1\dotheight}
{Lithos Pro-Black(0)}{1\dotheight}
{Marion Bold(0)}{0.8\dotheight}
{Marker Felt Thin(0)}{0.8\dotheight}
{Marker Felt Wide(0)}{1\dotheight}
{Menlo Italic(0)}{0.4\dotheight}
{Menlo Regular(0)}{0.4\dotheight}
{MesloLGS NF Italic(0)}{0.4\dotheight}
{MesloLGS NF Regular(0)}{0.4\dotheight}
{Myanmar MN Bold(0)}{0.8\dotheight}
{Noto Mono(0)}{0.5\dotheight}
{OCRAStd(0)}{0.3\dotheight}
{Pennstander Math Thin(0)}{0.4\dotheight}
{Phosphate Solid(0)}{1\dotheight}
{PoplarStd(0)}{1\dotheight}
{STHeiti(0)}{0.35\dotheight}
{STIX Two Text Bold(0)}{0.8\dotheight}
{STIX Two Text Bold Italic(0)}{0.8\dotheight}
{STSong(0)}{0.3\dotheight}
{Saira Stencil One Regular(0)}{1\dotheight}
{Songti SC Light(0)}{0.4\dotheight}
{Songti SC Regular(0)}{0.4\dotheight}
{Songti TC Light(0)}{0.4\dotheight}
{Songti TC Regular(0)}{0.4\dotheight}
{Verdana Bold(0)}{0.8\dotheight}
{XB Yas(0)}{0.4\dotheight}
{Yas(0)}{0.4\dotheight}
{Yas Italic(0)}{0.4\dotheight}
}{0.6\dotheight}
}
% special cases for some bold fonts
\str_if_eq:VnT \f@series {b} {
\dim_set:Nn \stroke {
\str_case_e:nnF {\f@family} {
{pcr}{0.5\dotheight}
{qcr}{0.9\dotheight}
{qzc}{0.5\dotheight}
{Courier New(0)}{0.8\dotheight}
{Lao MN(0)}{0.8\dotheight}
{Lithos Pro(0)}{1\dotheight}
{Myanmar MN(0)}{0.8\dotheight}
{STIX Two Text(0)}{0.8\dotheight}
{STIX Two Text (family)(0)}{0.8\dotheight}
{Thonburi(0)}{1\dotheight}
{Verdana(0)}{0.8\dotheight}
}{\stroke}
}
}
}
\newcommand{\quack}{%
\dim_set:Nn \Iheight {\fontcharht\font`I}
\getStrokeWD
\begin{tikzpicture}[baseline]
\draw[line~width=\stroke] (0,0) -- (\Iheight,\Iheight)
(0,\Iheight) -- (\Iheight,0);
\end{tikzpicture}~
}
\newcommand{\currentfont}{\f@family}
\makeatother
\ExplSyntaxOff
\begin{document}
%\huge
%\tiny
% list of fonts from https://tex.stackexchange.com/a/249140/36296
\foreach \macro in {
cmr, cmdh, cmss, cmtt, cmvtt, cmbr, ccr, clm, clmd, clms, clmqs, clmv, clmt, uaq, pbk, ptm, ppl, pnc, pag, phv, pcr, pzc, ugq, ugm, ua1, ulg, uop, zgmx, qag, qbk, qcr, qcs, qhv, qhvc, qpl, qtm, qzc, put, Heuristica-TLF, erewhon-OsF, bch, jkp, jkpl, jkpx, jkp, jkpss, jkpss, jkptt, Alegreya-OsF, Alegreya-TLF, AlegreyaSans-OsF, AmiciLogo, AnonymousPro, antp, antt, anttc, anttl, anttlc, AccanthisADFStdNoThree-LF, ybd, ybv, yes, GilliusADF-LF, GilliusADFNoTwo-LF, yly, MintSpirit-LF, yrd, UniversalisADFStd-LF, yvt, yv2, yv1, yv3, yvtd, yv1d, yvo, yvod, auncl, augie, AuriocusKalligraphicus, fav, fve, fvs, fvm, sqrc, DejaVuSerif-TLF, DejaVuSans-TLF, DejaVuSansMono-TLF, Cabin-TLF, Caladea-TLF, cantarell-OsF, Crlt-TLF, cmin, Cinzel-LF, CinzelDecorative-LF, ClearSans-TLF, comfortaa, cyklop, droidserif, droidsans, droidsansmono, EBGaramond-OsF, fbb-LF, FiraSans-TLF, frc, gentium, artemisia, bodoni, udidot, neohellenic, zi4, iwona, iwonac, iwonal, iwonalc, JanaSkrivana, kurier, kurierc, kurierl, kurierlc, lato-OsF, LibreBskvl-LF, LibreCsln-TLF, LinuxLibertineT-OsF, LinuxLibertineDisplayT-OsF, LinuxBiolinumT-OsF, LinuxLibertineMonoT-TLF, Lbstr-LF, LukasSvatba, ul9, Merriwthr-OsF, MerriwthrSans-TLF, nanummj, nanumgt, opensans-TLF, Ovrlck-LF, Ovrlck-LF, PlyfrDisplay-OsF, PTSerif-TLF, PTSerifCaption-TLF, PTSans-TLF, PTSansNarrow-TLF, PTSansCaption-TLF, PTMono-TLF, Quattro-LF, QuattroSans-LF, Raleway-TLF, Roboto-TLF, RobotoSlab-TLF, SourceCodePro-TLF, SourceSansPro-TLF, stix, trjn, yfrak%
}{
\normalfont
\fontfamily{\macro}
\selectfont
Nam dui ligula \quack Nam dui ligula (\currentfont)
\par
\bfseries
Nam dui ligula \quack Nam dui ligula (bold \currentfont)
\par
}
\end{document}
```
[](/image?hash=966a41c2b3e8680668d26cd2615c630f9ff71ea1cf2421a17a5d9ca49c998678)
(Click on the image to see the full list)I had a brilliant idea, really brilliant idea. I thought, the hyphen's height should correlate with the font weight. And for the first two fonts that's indeed the case, but not for CMR, which doesn't set a tight bounding box above the hyphen.
Next idea: The dot, provided it got a tight bounding box, should correlate with the weight. At least the three fonts you showcase in your questions in fact do have tight boxes.
Well, turns out that at least for the fonts you showcased plus the medium weight serif font of `kpfonts` the estimate works quite well when one checks how much bigger than 1pt the height of the dot is.
The first code block here has the heights calculated from the values you used (so should come pretty close to your `0.12\Iheight` and `0.1\Iheight` in the end).
```
\documentclass{article}
\usepackage{tgbonum}
\usepackage{tikz}
\newlength{\Iheight}
\newlength{\dotheight}
\newlength{\stroke}
\ExplSyntaxOn
\makeatletter
\newcommand{\quack}{%
\setlength{\Iheight}{\fontcharht\font`I}%
\dim_set:Nn \dotheight { \fontcharht\font`\. - 1pt }%
\str_case_e:nnF { \f@family }{
{qbk} { \dim_set:Nn \stroke { 5.71\dotheight } }
{bch} { \dim_set:Nn \stroke { 5.4\dotheight } }
% ....
}{
\dim_set:Nn \stroke
{
\bool_lazy_or:nnTF
% if the size is smaller than 1pt the formula wouldn't work well
{ \dim_compare_p:nNn \dotheight < \c_zero_dim }
% some arbitrary guess whether the bounding box is unreasonably big
{ \dim_compare_p:nNn \dotheight > { \f@size pt / 8 } }
{ 0.06 \Iheight }
{ 5.7 \dotheight }
}
}
\begin{tikzpicture}[baseline]
\draw[line~width=\stroke] (0,0) -- (\Iheight,\Iheight)
(0,\Iheight) -- (\Iheight,0);
\end{tikzpicture}~
}
\makeatother
\ExplSyntaxOff
\begin{document}
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{bch}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{cmr}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{jkp}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\end{document}
```

This here simply uses the factor 6 for all fonts (the difference to your hand selected values isn't that big actually):
```
\documentclass{article}
\usepackage{tgbonum}
\usepackage{tikz}
\newlength{\Iheight}
\newlength{\dotheight}
\newlength{\stroke}
\ExplSyntaxOn
\makeatletter
\newcommand{\quack}{%
\setlength{\Iheight}{\fontcharht\font`I}%
\dim_set:Nn \dotheight { \fontcharht\font`\. - 1pt }%
\dim_set:Nn \stroke
{
\bool_lazy_or:nnTF
% if the size is smaller than 1pt the formula wouldn't work well
{ \dim_compare_p:nNn \dotheight < \c_zero_dim }
% some arbitrary guess whether the bounding box is unreasonably big
{ \dim_compare_p:nNn \dotheight > { \f@size pt / 8 } }
{ 0.06 \Iheight }
{ 6 \dotheight }
}
\begin{tikzpicture}[baseline]
\draw[line~width=\stroke] (0,0) -- (\Iheight,\Iheight)
(0,\Iheight) -- (\Iheight,0);
\end{tikzpicture}~
}
\makeatother
\ExplSyntaxOff
\begin{document}
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{bch}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{cmr}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\bigskip
\fontfamily{jkp}\selectfont
Nam dui ligula Nam dui ligula
Nam dui ligula \quack Nam dui ligula
Nam dui ligula Nam dui ligula
\end{document}
```
