Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Proposal: File Format Versions 1, 2 and Beyond #4

@nigeltao

Description

@nigeltao

Summary

I propose to:

  • Retroactively name the current (as of May 2021) IconVG wire format as FFV 0 (File Format Version 0).
  • Consider FFV 0 a deprecated experiment and no longer supported.
  • Introduce FFV 1 as a subset (in terms of features) of FFV 0 but incompatible (in terms of wire format), in order to remove features that are hard to combine with animation, and to clean up some design warts.
  • FFV 2 (if it happens, in the future) will be a superset of FFV 1 in terms of both features and wire format (other than a one-byte-change version-number bump). The intended headline feature for FFV 2 is animation (issue Animation #2). FFVs 1 and 2 can equivalently be considered Small and Large profiles of the overall IconVG file format. For example, a future font format could embed FFV 1 (static) graphics but not FFV 2 (static and animated).

Background

Since its inception in 2016, IconVG has always carried the caveat that "WARNING: THIS FORMAT IS EXPERIMENTAL AND SUBJECT TO INCOMPATIBLE CHANGES".

Issue #2 in this repository is about adding animation to IconVG graphics. Tweening would almost certainly involve transformations (in the "affine transformation" sense) and interpolation.

The original IconVG design took the entirety of the SVG path model, including elliptical arc segments. Unlike line_to, quad_to and cube_to, arc_to's parameterization is unique, not being a sequence of (x, y) coordinate pairs, and a boolean argument like large-arc-flag is impossible to interpolate smoothly.

Rasterization backends like Cairo and Skia also don't provide arc_to as a primitive, or if they do, not in the way that SVG parameterizes it. We usually approximate arcs as cubic splines.

Also recall that IconVG is a presentation format, not an authoring format, and it already isn't able to represent groups, strokes, text, etc 'natively'. Authoring tools like Illustrator or Inkscape, if they could export to IconVG, are expected to 'lower' e.g. stroked paths to more primitive operations (filled paths), the same way that they would 'flatten' layers if exporting to PNG. I'd expect such tools could also 'lower' arcs to cubic Béziers during export.

Thus, I'm considering removing arcs from the file format. This new version (File Format Version 1) would not be a superset of FFV 0 per se, but FFV 0 files could be converted in a straightforward way and the rasterizations would be equivalent. In essence, 'lowering' arcs becomes the responsibility of the authoring tools (which get more complicated) instead of the presentation tools (which get simpler).

Separately, the original Go implementation (the golang.org/x/exp/shiny/iconvg package in a separate repository) was released as an interim milestone of the unfinished 'Shiny' Go GUI project. IconVG hasn't had much adoption so far, as the only implementation was in Go and so not usable from e.g. C++, Dart or Python GUI programs. In recent weeks, this repository has gained a brand new C implementation, but we still don't yet have a vast back-catalogue of existing IconVG files to constrain us.

Bringing all of the above together, if I were ever to make an IconVG FFV 1, especially one that isn't a superset of FFV 0 (because arcs), then now is the time to do it.

This issue is a place to discuss that process and what other features to add or warts to remove as part of FFV 1.

File Format Changes

See the spec for context.

The major change is:

  • Remove the A and a arc-related drawing opcodes.

Minor clean-up changes are:

  • Change the first byte of the magic header from 0x89 to 0x8A, so that we can distinguish IconVG from PNG (from JPEG from WebP etc) just from the first byte of the file. https://en.wikipedia.org/wiki/List_of_file_signatures doesn't show any previous claims on 0x8A.
  • Add an explicit FFV number in the wire format. Specifically, change the fourth byte of the magic header from 0x47 (ASCII 'G') to 0x31 (ASCII '1') for FFV 1, 0x32 (ASCII '2') for FFV 2, etc.
  • MID numbers must use the shortest possible encoding.
  • Re-number the ViewBox and Suggested Palette MIDs (Metadata IDs) from 0 and 1 to 8 and 16 (which are represented on the wire as 0x10 and 0x20). Since metadata is presented in increasing MID order, the gaps allow future extensions to insert (optional) metadata chunks before these existing ones.
  • Prohibit encoded real numbers being NaNs. In the end state, the spec should no longer mention "undefined behavior".
  • Tighten restrictions on gradients: there must be at least two stops and the offsets must span from 0 to 1 inclusive.
  • Maybe some other small things I've forgotten.

Implementations

  • This repository's C and Go libraries (the latter also to be called the 'new' Go library) will speak FFVs 1+ but not FFV 0.
  • The original written-in-2016 Go library (the 'old' Go library), at golang.org/x/exp/shiny/iconvg, will speak FFVs 0 and 1+, delegating the latter to the 'new' Go library.
  • The 'old' Go library will also gain tools to upgrade FFV 0 files to FFV 1.

Notably, any existing Go code (using the 'old' Go library) displaying existing (FFV 0) files will continue to work.

Timeline

FFV 1 should be finalized 'soon'. FFV 2 is more open ended and will require extensive prototyping.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions