Skip to content

VariantPreview

Namespace Nfty.Core.Imaging in assembly Nfty.Core.

public static class VariantPreview

Renders one Variant exactly as generation would: colorized from its value-map for Dynamic and Static layers, passed through untouched for Custom. This lived inline in the CLI's preview command, whose own comment warned that the point is "a preview shows exactly what generation would render rather than a second, drifting implementation". Wiring the GUI to its own copy would have created exactly that second implementation, so the rule now lives here and both front-ends call it.

Methods

NeedsColor(LoadedIngredient)

public static bool NeedsColor(LoadedIngredient ingredient);

Whether ingredient needs a color to be previewed. Custom does not; a UI can use this to decide whether to ask.

Parameters

  • ingredient (LoadedIngredient) - The layer to ask about.

Returns. True for a Dynamic or Static layer; false for Custom, which is never colorized.

Render(LoadedIngredient, string, RolledColor, ColorModel?)

public static Image<Rgba32> Render(LoadedIngredient ingredient, string variantId, RolledColor color, ColorModel? modelOverride = null);

The rendered variant, colorized from an already-rolled hue and saturation rather than from a spec string. The caller owns the returned image, exactly as with the spec overload.

This is the path generation itself takes: ColorRoller.Roll produces a continuous RolledColor and hands it straight to Colorizer.Apply, with no string in between. The spec overload cannot match that for a rolled color — every color spec resolves back through 8-bit RGB, so a hue that fell between two representable colors comes back as the nearest one and the preview lands within a rounding step of the asset instead of on it. Small (about a quarter-degree of hue), but this class's whole promise is "exactly as generation would", and a value that was never quantized must not be quantized on its way to being shown.

A Static layer needs no such overload: its color is an author-written spec, so generation resolves the same string through the same parser and the spec overload is already exact. Only a rolled color has a value with no exact spelling.

Parameters

  • ingredient (LoadedIngredient) - The layer the variant belongs to; supplies the kind and the color model.
  • variantId (string) - Which variant of it to render.
  • color (RolledColor) - The rolled hue and saturation, unrounded.
  • modelOverride (ColorModel?) - Renders in a different color model than the ingredient declares. Null uses the ingredient's own.

Returns. The rendered image; the caller owns it. A Custom layer is cloned as-is and the color is ignored, since Custom is never colorized.

Render(LoadedIngredient, string, string?, ColorModel?)

public static Image<Rgba32> Render(LoadedIngredient ingredient, string variantId, string? colorSpec = null, ColorModel? modelOverride = null);

Renders one variant of a layer, colorized from a prefixed color spec the way a Static layer's fixed color is at generation time.

Parameters

  • ingredient (LoadedIngredient) - The layer the variant belongs to; supplies the kind and the colorization.
  • variantId (string) - Which variant of it to render.
  • colorSpec (string?) - A prefixed color spec (hex:, rgb:, hsl:, hsv:). Required for a colorized layer; ignored for Custom.
  • modelOverride (ColorModel?) - Renders in a different color model than the ingredient declares, for comparing the two. Null uses the ingredient's own.

Returns. The rendered variant. The caller owns the returned image and must dispose it — including for a Custom layer, where a CLONE is returned rather than the ingredient's own image. Returning the borrowed one for one kind and an owned one for the others would make disposal depend on the layer kind, which is exactly the sort of ownership rule that gets a double-free or a leak eventually.

Exceptions

  • InvalidOperationException - The layer is colorized but colorSpec is null, or it carries no colorization block.
  • FormatException - colorSpec is not a valid prefixed color spec.