drewnoakes / figgle

ASCII banner generation for .NET
Apache License 2.0
412 stars 42 forks source link

suggestion: unbundle fonts from engine #12

Open zmira opened 2 years ago

zmira commented 2 years ago

Hi.

Would it be possible to unbundle the fonts from the engine, i.e. in split into two nuget packages? This way the base engine nuget package would be much leaner.

Currently it ships as a 474KB DLL, of which ~90% alone are due to Fonts.zip as an embedded resource. As a comparison, having two separate DLLs, the DLL for the engine would be ~15KB and the DLL for the fonts would be ~464KB (and would depend on the engine DLL).

Since the engine already allows external fonts to be loaded, it would not be that hard for a user of the engine to load a font either from the unbundled fonts package or from disk.

Just an idea...

Thanks.

drewnoakes commented 2 years ago

Thanks for the suggestion. This has crossed my mind too.

I need to find time to finish up the source generator too. For people who only render statically known strings, this allows the conversion to happen at compile time so that you don't need to deploy any Figgle libraries at all.

drewnoakes commented 1 year ago

The source generator is now available. If the text you are rendering is known at compile time, you can avoid shipping Figgle with your app at all. There's still a valid use case for separating out the fonts from the engine, however.

HowardShank commented 5 months ago

@drewnoakes I'll have to give some thought to a full solution to the font separation challenge. My down and dirty hack let me create a 22kb dll with only the fonts I wanted in it.

To do this as a bigger package will take some thought.

drewnoakes commented 5 months ago

One option is to split the package in two, so we have one for the core Figgle code, and another with fonts. On the plus side, that would allow a smaller deployment, but on the negative side it makes it harder to consume the library. Everyone will need at least one font, and if all the fonts are in a separate package then I expect most people would end up with two package references anyway, which is worse both from ergonomics and performance (loading two DLLs is worse than loading one).

Another option is to create a separate NuGet package for every font. This gives fine-grained control over what's loaded, but makes it harder to explore different fonts, which is half the fun of this library.

HowardShank commented 5 months ago

What about: Source contains all the fonts you want to make available. Some pre-compile time process allows some sort of picker to select fonts to be bundled. At compile time the zip file is assembled from project fonts marked to be included into the assembly? Then using something like AOP the FiggleFonts class could have the public static FiggleFont Standard => GetByName("standard"); statements created at compile time including only what was selected.

drewnoakes commented 5 months ago

Perhaps the source generator could help here. There might be a mode where it would add the figlet text for any fonts you actually use. This would still require a package that contains the engine alone.

Something like

[EmbedFiggleFont(FiggleFonts.Standard)]
internal static partial class MyFiggleFonts
{
}

// Then you'd write
MyFiggleFonts.Standard.Render("Hello World, from My Font");

// And the generated code would resemble
internal static partial class MyFiggleFonts
{
    private const string standardFontText = """
        flf2a$ 6 5 16 15 11 0 24463 229
        Standard by Glenn Chappell & Ian Chai 3/93 -- based on Frank's .sig
        Includes ISO Latin-1
        figlet release 2.1 -- 12 Aug 1994
        Modified for figlet 2.2 by John Cowan <cowan@ccil.org>
          to add Latin-{2,3,4,5} support (Unicode U+0100-017F).
        Permission is hereby given to modify this font, as long as the
        modifier's name is placed on a comment line.

        Modified by Paul Burton <solution@earthlink.net> 12/96 to include new parameter
        supported by FIGlet and FIGWin.  May also be slightly modified for better use
        of new full-width/kern/smush alternatives, but default output is NOT changed.
         $@
         $@
         $@
         $@
         $@
         $@@
          _ @
         | |@
         | |@
         |_|@
         (_)@
            @@
        // etc...
        """";

    public static FiggleFont Standard { get; }

    static MyFiggleFonts()
    {
        StringPool pool = new();
        Standard = FiggleFontParser.Parse(standardFontText, pool);
    }
}