The coming of SVG
Mark Waddingham
mark at livecode.com
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
effects.
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:
https://github.com/livecode/livecode/pull/6099/commits/3c706ad92dff07f6db23fb24e3755e18fe30f011
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
natural.
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,
Mark.
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.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list