Revision 1

Solartech Formatted Message Format 2

The goal of the Solartech Formatted Message (SFM2) format is to allow people to create pages with specified font sizes, line breaks, etc. It is, necessarily, an alternative to MULTI (the NTCIP format), but it's not a direct competitor, in that it's not concerned with feature parity or compatibility.

Unlike SFM, SFM2 specifies a dynamic page, with animated built-in graphics and flashing lines.

SFM2 pages are encoded in unicode, with a 3-byte binary header. The first byte is a binary encoding of the number of lines in the page. The second and third bytes are a big-endian unsigned short indicating the size of the rest of the page in bytes (basically, something suitable to be read in by Java's DataInput.readUTF()).

SFM2 is a tagged language. For the sake of easy parsing and reduced storage space, tags will be special characters, mostly from the unused portion of the first unicode plane (historical ascii) which historically came from terminal types, and are consequently completely useless in our context. Tags are not just escape characters, though, they may begin an escape sequence. (The most obvious is the named font escape tag.)

Lines are terminated by newline characters ("\n", i.e. 0x000a). Since determining newlines means parsing the entire mesage (since the length of a font name could easily be 10), the number of lines in the page is encoded in the first byte. For simplicity of parsing, every line must be terminated with a newline, including the last. This is true even if the page is one line long.

Font tags switch the current font. All of the characters on a line are aligned to the same baseline; characters in larger fonts are simply taller. Lines which are either too tall or too long should simply be truncated.

If no font is specified via a tag, the default font is 7pxRoadSafety-normal.

Built-In Graphics

There are a number of built-in graphics which an SFM2 message may specify. Built-in graphics take the place of the line which they are specified on, so if there is any text on that line, it is ignored. If there is more than one graphic specified on a line, it is undefined which one wins. Built-in graphics may be static or animated.

The built-in graphics are:

Built-In Graphics
ID Graphic
0 Left Static Arrow
1 Right Static Arrow
2 Left Animated Arrow
3 Right Animated Arrow
4 Left Animated Chevrons
5 Right Animated Chevrons

Flashing may be specified for static images. If it is specified on a line with animated graphics, the flashing tag is ignored.

Flashing Lines

If the flashing tag is specified on a line, that entire line flashes. The flashing rate may be specified in deciseconds for on-time and off-time. If a flashing tag is specified on the same line as an animated graphic, the flashing tag is ignored.

Escape Sequences

The special escape characters are:

Escape Characters
Escape Character Name Meaning
0x0000 Reserved There's no good reason not to use 0x0000 as a tag, but given how often null is used as something special, it's probably best to avoid it.
0x0001 1 Line This tag switches the current font to 20pxRoadSafety
0x0002 2 Line This tag switches the current font to 11pxRoadSafety
0x0003 3 Line This tag switches the current font to 7pxRoadSafety-normal
0x0004 3 Line Bold This tag switches the current font to 7pxRoadSafety-bold
0x0005 3 Line Narrow This tag switches the current font to 7pxRoadSafety-narrow
0x0006 3 Line Condensed This tag switches the current font to 7pxRoadSafety-condensed
0x0007 4 Line This tag switches the current font to 5pxRoadSafety
0x0008 Specified Font This tag is used to specify a font by name. Immediately following two (ascii) numerals indicating the length of the font name, followed by the name. This name is the full name of the font to use.
0x000b Builtin Graphic This tag is used to specify a builtin graphic. Immediately following are two (ascii) numerals which gives the builtin ID (see above)
0x000c Flash Causes the line it's found in to flash. Immediately followed by two ascii numerals, the first giving the on time and the second giving the off time, both in deciseconds minus one (that is, the real value is one greater than the numeral).