Designing a custom single stroke font

Hi! I’ve been wondering if it is possible to design a custom font that works in a similar way to the default NewStroke font. It’s defined by a single stroke, and allows you to set a custom stroke width in the pcb editor. External fonts that come in standard font formats don’t allow this.

The NewStroke font can be edited in the kicad symbol editor, and is composed of polygons :

My question is, can i modify the default font and somehow export it, so that it can be used by kicad in the same way as NewStroke?
I could edit it in the source code and compile the program with my modified version of the font, but that feels like a very suboptimal way of doing things, plus i’d lose the option of choosing between NewStroke and my custom font.

Can you use any of the Hershey engraving fonts for this? I’ve not tried using them in KiCad but I have used them via Inkscape for engraving using a CNC machine.

https://www.evilmadscientist.com/2011/hershey-text-an-inkscape-extension-for-engraving-fonts/

Having looked at it better now, the newstroke font gets converted into an encoding that is basically the same as the Hershey font format. Which makes sense, given that KiCAD used to use Hershey’s font before NewStroke was introduced.

kicad/common/newstroke_font.cpp lines 154-173:

const char* const newstroke_font[] =
{
    /* // BASIC LATIN (0020-007F) */
    "JZ", /* U+20 SPACE  */
    "MWRYSZR[QZRYR[ RRSQGRFSGRSRF",
    "JZNFNJ RVFVJ",
    "H]LM[M RRDL_ RYVJV RS_YD",
    "H\\LZO[T[VZWYXWXUWSVRTQPPNOMNLLLJMHNGPFUFXG RRCR^",
    "F^J[ZF RMFOGPIOKMLKKJIKGMF RYZZXYVWUUVTXUZW[YZ",
    "E_[[Z[XZUWPQNNMKMINGPFQFSGTITJSLRMLQKRJTJWKYLZN[Q[SZTYWUXRXP",
    "MWSFQJ",
    "KYVcUbS_R]QZPUPQQLRISGUDVC",
    "KYNcObQ_R]SZTUTQSLRIQGODNC",
    "JZRFRK RMIRKWI ROORKUO",
    "E_JSZS RR[RK",
    "MWSZS[R]Q^",
    "E_JSZS",
    "MWRYSZR[QZRYR[",
    "G][EI`",
    "H\\QFSFUGVHWJXNXSWWVYUZS[Q[OZNYMWLSLNMJNHOGQF", /* U+30 DIGIT_0  */

...

“futural” from Hershey’s fonts:

12345  1JZ
12345  9MWRFRT RRYQZR[SZRY
12345  6JZNFNM RVFVM
12345 12H]SBLb RYBRb RLOZO RKUYU
12345 27H\PBP_ RTBT_ RYIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX
12345 32F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT
12345 35E_\O\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\Z\Y
12345  8MWRHQGRFSGSIRKQL
12345 11KYVBTDRGPKOPOTPYR]T`Vb
12345 11KYNBPDRGTKUPUTTYR]P`Nb
12345  9JZRLRX RMOWU RWOMU
12345  6E_RIR[ RIR[R
12345  8NVSWRXQWRVSWSYQ[
12345  3E_IR[R
12345  6NVRVQWRXSWRV
12345  3G][BIb
12345 18H\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF
...

So it seems like KiCAD can parse hershey’s font format, but it can’t do that for external fonts (yet).

kicad/common/font/font.cpp lines 173-178:

bool FONT::IsStroke( const wxString& aFontName )
{
    // This would need a more complex implementation if we ever support more stroke fonts
    // than the KiCad Font.
    return aFontName == _( "Default Font" ) || aFontName == KICAD_FONT_NAME;
}

Newstroke is built in to the binaries. I don’t see any other option than to do what you already described, “edit it in the source code and compile the program with my modified version of the font”.

The built-in font system is probably as old as KiCad itself. True Type and Open Type were added much later and use a completely different mechanism, harfbuzz.

I don’t know if there’s an issue for this, maybe you could create one.

As a curiosity, I found this in common/stroke_font.cpp:

STROKE_FONT* STROKE_FONT::LoadFont( const wxString& aFontName )
{
    if( aFontName.empty() )
    {
        STROKE_FONT* font = new STROKE_FONT();
        font->loadNewStrokeFont( newstroke_font, newstroke_font_bufsize );
        return font;
    }
    else
    {
        // FONT TODO: support for other stroke fonts?
        return nullptr;
    }
}

Yes, I think the way to get this would be to build the feature into KiCad (that TODO) and submit a MR for it. While you could also just create an issue, this is one of those niche things that I think is pretty unlikely to get implemented by the core team (but could be wrong)