The coming of SVG

Mark Waddingham mark at
Thu Nov 9 11:08:21 EST 2017

On 2017-11-09 15:13, hh via use-livecode wrote:
> @Mark.
> You wrote several times
> "... the LCB canvas abilities ..., which are a superset of the HTML5
> Canvas abilities"
> It is just now more "planned to be a superset"?
> The HTML5 canvas has for example the ability to set and get dataURLs.
> And LCB doesn't even have a base64 encoder/decoder.

It is already superset in terms of anything the HTML5 canvas can draw, 
the LCB canvas can draw.

Specifically, the LCB canvas is a superset because it also supports 
transparency layers with local opacity, local blend modes and bitmap 

The way you can get image data in is not quite the same as HTML5, 
admittedly: we have from binary data, local files, resource files and 
pixel data whereas HTML5 allows referencing image-like elements, remote 
URLs and data URLs. (The latter are subsumed by the 'with data' 
constructor for LCB images though).

Ignoring images for the moment, the critical API differences are that 
the HTML5 canvas allows specifying distinct fill and stroke paints - 
which are used for 'fill' and 'stroke' operations.

The latter I've already done a rough patch for here:

This adds fillPaint/strokePaint/fillOpacity/strokeOpacity properties; a 
'draw' command; the notion of 'no paint' and a transform property. The 
fill command uses the fillPaint, the stroke command uses the stroke 
paint and the draw command fills (if the fill paint is not 'no paint') 
then strokes (if the stroke paint is not 'no paint'). The transform 
property allows you to specify the transform to be applied since the 
last 'save' - this means you can change the current (local) transform by 
setting a property rather than doing a little save/restore dance.

I must confess that I'm less interested in parity with the HTML5 canvas 
(which one can always assume will be a subset of SVG capabilities) than 
parity with SVG.

It seems a little silly to me that the HTML5 Canvas element has *not* 
been 100% based around what operations you need to render a suitably 
processed SVG file - particularly as all the major browsers support a 
large majority of all the existing SVG specs (and so, by extension all 
the major browsers must have 2d graphics support which is 'good enough' 
to render SVG). (Although, to be fair here, I didn't see that potential 
correspondence when I was designing the LCB Canvas API with Ian - so I 
guess I can't cast too many aspersions!)

Critically, you can see the effect of these very small changes to the 
LCB Canvas API by looking at the changes it allowed me to make to the 
vectoricon implementation (the vectoricon.lcb diffs in the above 
commit). With those changes, there is a 1-1 correspondence between 
canvas commands and each SVG property and SVG shape element - which 
means that any sort of 'metafile' representation of SVG is entirely 

In terms of the image referencing support, then there are perhaps two 
missing pieces - the ability to reference an image script object (i.e. 
an image object), and the ability to reference a URL. Adding an LCB 
Image data URL constructor would be straightforward - remote URLs would 
be possible to, but would require a bit more infrastructure (and a 
callback to use libUrl).

In terms of where we are at the moment - the above patch needs a little 
more thought. Those initial changes give us a 1-1 correspondence between 
flattened SVG (i.e. where it has been converted to a sequence of shapes 
with fill/stroke attributes) and the LCB Canvas API; but not (strictly 
speaking) a 1-1 correspondence for direct execution of an SVG file (my 
last comment on the associated PR there explains that).

That patch is backwards-compatible (setting paint sets fill and stroke 
paints, getting paint gets the fill paint). However, the further change 
I'd like to make is three fold:

   - get rid of save/restore, replacing them with begin/end (just without 
creating a transparency layer)

   - make all inheritable SVG fill/stroke related properties be 'the 
value set since the last begin' or nothing if they haven't

   - add effective forms of all the fill/stroke related properties which 
return the *current* value taking into account inheritence

The above need significantly more thought with regards backwards 
compatibility though.

Looking forward, there are features that full SVG needs which the LCB 
canvas does not - so it would be good to add them in the same model; 
however, that would be watered down somewhat if the fundamentals did not 
match - which is one motivation here (another motivation here, I will 
admit is an element of 'structural beauty' which is perhaps, slightly 
less pragmatic!).

So - yes there are a few differences between HTML5 Canvas and LCB Canvas 
currently, but there is a clear path to resolving that inline with the 
goal of making the LCB Canvas (essentially) an SVG-capable canvas - i.e. 
allowing implementation of rendering SVG to be as clean and as simple as 
possible; with no points of friction.

Anyway, in terms of right now, it seems a bit silly to sit here with a 
perfectly reasonable SVG implementation which can render all sorts of 
SVG files correctly right now whilst we spend time fettling with what 
are (in essence) some technical details.

We already have an object which has the right name for display of 
something image-like (the image object); that object already hooks into 
icons/imagesources - which is the way the majority of SVG files will 
likely want to be used; so pragmatism says that the best approach is to 
work to integrate what we have now into that object in a display only 
way; and then look to the future to expand what we can do with SVG in 
LiveCode (e.g. the 'canvas' control or whatever it might be called).

Warmest Regards,


P.S. Could you file an enhancemnt request for 'image from url' - in the 
first instance we can certainly implement data urls, remote urls will 
need a fair bit more thought and time.

Mark Waddingham ~ mark at ~
LiveCode: Everyone can create apps

More information about the use-livecode mailing list