Skip to content

Ensure font fallback is to "font" and not just to "typeface"#330

Open
MatteoH2O1999 wants to merge 2 commits intoBinaryKits:developfrom
MatteoH2O1999:font-management
Open

Ensure font fallback is to "font" and not just to "typeface"#330
MatteoH2O1999 wants to merge 2 commits intoBinaryKits:developfrom
MatteoH2O1999:font-management

Conversation

@MatteoH2O1999
Copy link
Copy Markdown
Contributor

@MatteoH2O1999 MatteoH2O1999 commented Jan 21, 2026

Right now, when a font is not found and a fallback is used, as in the default fontLoader

if (fontName == "0")
{
    return this.Typeface0;
}

return this.TypefaceA;

the scaling matrices are not applied, as it is just a fallback on the SKTypeface, not the font.

Thus we can change the logic of the fontloader (backwards compatible): if it returns null, the font is considered not found and a fallback can be used instead if the consumer chooses so.

An output parameter allows us to know whether we are using the fallback or not.
This way, we are truly falling back on font A, not just its typeface.

This changes nothing for fontLoaders that never return null.

@MatteoH2O1999
Copy link
Copy Markdown
Contributor Author

cc @primo-ppcg

@primo-ppcg
Copy link
Copy Markdown
Collaborator

Do you have a explicit example of an incorrect label that this PR corrects?

@MatteoH2O1999
Copy link
Copy Markdown
Contributor Author

MatteoH2O1999 commented Jan 26, 2026

^XA
^CFI,30,30^FO300,300^FDTestTest^FS
^XZ

of course you then need to edit the font loader:

if (fontName == "0")
{
    return this.Typeface0;
}

if (fontName == "I")
{
    return null;
}

return this.TypefaceA;

otherwise the old behavior is mainteined.

We are trying to replicate labelary, so we use the following fontLoader:

public static readonly Func<string, SKTypeface?> FontLoader = fontName =>
            fontName switch
            {
                "0" => font0,
                "A" => fontA,
                "B" => fontB,
                "C" or "D" => fontCD,
                "E" => fontE,
                "F" => fontF,
                "G" => fontG,
                "H" => fontH,
                "J" => fontJ,
                "L" => fontL,
                "N" => fontN,
                "P" => fontP,
                "Q" => fontQ,
                "R" => fontR,
                "S" => fontS,
                "T" => fontT,
                "U" => fontU,
                "V" => fontV,
                _ => null,
            };

@primo-ppcg
Copy link
Copy Markdown
Collaborator

We are trying to replicate labelary

We are not trying to replicate labelary. We are attempting to replicate the output of a ZPL enabled printer.

@MatteoH2O1999
Copy link
Copy Markdown
Contributor Author

MatteoH2O1999 commented Jan 27, 2026

If a zpl printer does not find a font, it uses a fallback font. Not a fallback typeface with no scaling matrix.

Our specific use case was just one explicit example (like you requested) where the library has a wrong fallback behavior

@MatteoH2O1999
Copy link
Copy Markdown
Contributor Author

Once again, this is a backwards compatible change: if the fontLoader could not return null, nothing changes, if it could, it would have thrown before so it was already broken.

In addition, this is the correct interpretation according to the ZPL standard as you can see here.
Citing from there:

If you do not change the alphanumeric default font and do not use any alphanumeric field command (^AF) or enter an invalid font value; any data you specify prints in font A.

As you can see, it says it uses font A. Not just its typeface. Font A. Together with its scaling matrix. Something that right now this library does not allow.

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