Font with outlines

Okay, I got Slate font outlines working in 4.8 with one engine C++ file change. I wanted to hack this in with as minimal changes to the engine code as possible, so it all lives inside Engine\Source\Runtime\Slate\Private\Framework\Text\SlateTextRun.cpp. This isn’t the “right” way to do outlines as Nick mentions above, and it’s certainly not efficient if you start doing very thick outlines, but it will get the job done if you’re after a quick fix. Here’s what it looks like in action with an outline and drop shadow:

SDROutline.png

And a more extreme example, showing some ugliness on the outline corners:

SDROutlineThick.png

Some notes:

  • The basic idea is to draw the outline similar to the way we draw the drop shadow (a copy of the text drawn underneath the main text with an offset), except we draw multiple “shadows” in a circular pattern around the text to fake the outline. Note that this means you’re potentially redrawing text quite a lot depending on the outline parameters you choose, so be weary of performance.
  • I’ve hijacked Slate’s ShadowOffset vector to carry some extra data for the outline: Outline thickness, and outline directions. These values are packed in by multiplying them by 1000, relying on the fact nobody wants shadow offsets greater than 500 Slate units. You can change this multiplier to be higher if necessary.
  • Outline thickness defines how thick the outline should be in Slate units. eg. 3 would mean 3 pixels thick assuming no DPI scaling.
  • Outline directions is the number of directions in a circle (think of a compass) we should redraw the outline text. eg. 8 would mean redraw the text 8 times in compass directions N, NE, E, SE, S, SW, W, NW.
  • I’m currently just using the shadow color and opacity for the outline color and opacity. You could hardcode it to something else if you wanted (eg. black) or do some more crazy hijacking of the ShadowColorAndOpacity color to pack 2 colors in there, but I’ll leave that as a reader exercise. :slight_smile:
    For the example picture above I used the following code in my Slate style definitions. The SetShadowOffset parameter takes secret parameters (multiply them by magic number 1000) and can be thought of as a shadow offset of (7, 10), an outline thickness of 3 and 8 outline directions


Style.Set("SpaceDustRacers.MenuHeaderTextStyle", FTextBlockStyle()
		.SetFont(OTF_FONT("Fonts/Molot", 115))
		.SetColorAndOpacity(FLinearColor::White)
		**.SetShadowOffset(FIntPoint(7 + 3000, 10 + 8000))**
		);


The SlateTextRun.cpp code changes are here (against UE4.8 baseline): Unreal Engine 4.8 Slate font outline hack - SlateTextRun.cpp - Pastebin.com

For clarity’s sake, I’ve added a macro (yes I am aware of the irony) to my game-side Style definitions:


#define SHADOW_OFFSET_AND_OUTLINE(ShadowOffsetX, ShadowOffsetY, OutlineThickness, OutlineDirections) FIntPoint((ShadowOffsetX) + ((OutlineThickness) * 1000), (ShadowOffsetY) + ((OutlineDirections) * 1000))

	Style.Set("SpaceDustRacing.MenuHeaderTextStyle", FTextBlockStyle()
		.SetFont(OTF_FONT("Fonts/Molot", 115))
		.SetColorAndOpacity(FLinearColor::White)
		.SetShadowOffset(SHADOW_OFFSET_AND_OUTLINE(0, 10, 3, 8))
		);


Enjoy. :slight_smile: