svg-lmtx.tex /size: 16 Kb    last modification: 2023-12-21 09:43
1% language=us runpath=texruns:manuals/svg
2
3% \enabletrackers[metapost.svg.result]
4% \enabletrackers[metapost.svg.path]
5
6% \enabledirectives[pdf.compact]
7
8% \nopdfcompression
9
10\usemodule[svg]
11\usemodule[abbreviations-logos]
12\usemodule[scite]
13
14\setuppapersize
15  [A4,landscape]
16
17\setuplayout
18  [backspace=1cm,
19   cutspace=2cm,
20   topspace=1cm,
21   width=middle,
22   height=middle,
23   header=0pt,
24   footer=0pt]
25
26\setupbodyfont
27  [dejavu,12pt]
28
29\setupwhitespace
30  [big]
31
32\setuphead
33  [chapter]
34  [style=\bfc,
35  color=darkblue]
36
37\setuphead
38  [section]
39  [style=\bfb,
40   color=darkblue]
41
42\starttext
43
44\startMPpage
45    drawlineoptions   (withpen pencircle scaled 0.4 withcolor darkgray) ;
46    drawpointoptions  (withpen pencircle scaled 0.8 withcolor darkred) ;
47    drawcontroloptions(withpen pencircle scaled 0.6 withcolor darkgreen) ;
48    drawpathoptions   (withpen pencircle scaled 1.0 withcolor darkblue) ;
49
50    drawoptionsfactor := .5 ;
51    detailpaths ;
52
53    StartPage ;
54
55        fill Page withcolor darkblue ;
56
57        draw lmt_svg [
58            filename = "svglogo.svg",
59            origin   = true,
60        ]
61            ysized (PaperHeight -64mm)
62            shifted (12mm,52mm) ;
63
64        draw textext.llft ("\strut in context")
65            ysized 34mm
66            shifted lrcorner Page
67            shifted (-8mm,84mm)
68            withcolor white ;
69
70        draw textext.llft ("\strut and metafun xl")
71            ysized 34mm
72            shifted lrcorner Page
73            shifted (-8mm,44mm)
74            withcolor white ;
75
76
77    StopPage ;
78\stopMPpage
79
80\starttitle[title=Introduction]
81
82This document is about using \SVG, an \XML\ based format for describing graphics
83and colorful font shapes in \CONTEXT. It's one of the external figure formats.
84Where we can use \METAPOST\ for all kind of systematic graphics, bitmap images
85and artistic outlines come from outside. Inclusion of \SVG\ using the methods
86discussed here is quite efficient and will work for many graphics, but when it
87doesn't you can always fall back on a conversion by \INKSCAPE. It's work in
88progress anyway.
89
90The document is made for viewing on the screen and has a bunch of examples taken
91from websites. We might add more in due time. The cover page has the \SVG\ logo
92taken from \WIKIPEDIA\ but with some details added. It's not a nice cover image
93but it will do for our purpose. Feel free to suggest additional examples.
94
95\startlines
96Hans Hagen
97Hasselt NL
98October 2019\high{+}
99\stoplines
100
101\stoptitle
102
103\starttitle[title=The \SVG\ format]
104
105\startsection[title=What it is]
106
107The Scalable Vector Graphics format (\SVG) showed up around the turn of this
108century. I remember looking into it and wondering to what extent it was a fresh
109development and not some kind of application format turned \XML. Most elements
110are empty elements and data lives in attributes. What I found most puzzling is
111that a path definition was an attribute and not just content, especially because
112it can be a pretty large blob of numbers and commands. Anyway, at that time I
113played a bit with conversion but in the end decided to just consider it an
114external format for which conversion to (say) \PDF\ by an external program was a
115reasonable. At some point that external program became \INKSCAPE\ and \CONTEXT\
116uses that to convert \SVG\ images to \PDF\ runtime (with caching).
117
118In the meantime edition one turned edition two and the advance of \HTML\ and
119\CSS\ has crept features into the format, thereby not making it look better. But,
120because viewers support rendering \SVG, we now also see graphics showing up. The
121ones that I have to deal with are educational graphics, and when you look into
122the files, they can be curiously inconsistent in the way parts of graphics are
123made. For instance, the numbers along an axis of a mathematical graphic can be a
124mix of references to a font (\type {<text/>}), references to symbols \type
125{<symbol/>} that have paths (\type {<path/>}) or just paths \type {<path/>}.
126Using a tool that can spit out something structured doesn't mean that all its
127users will structure.
128
129The \SVG\ format provides lines, rectangles, circles, ellipses, polylines,
130polygons and paths. Paths are defines as a sequence of moves, lines, cubic and
131quadratic curves, arcs, collected in the \type {d} attribute (a funny short name
132compared to the length of its content and the verbosity of other attribute
133names). They can be open or closed, and use different winding rules. Positions
134are absolute or relative. This all leaves a lot of room for error and confusion.
135When a path looks bad, it can be produced bad, or the interpretation can be bad.
136Interpretation can even be such that errors are catched which makes it hard to
137figure out what is really wrong. And as usual, bugs (and supposed catches) can
138become features in the end. So it might take a while before this kind of support
139in \CONTEXT\ becomes stable but once it is, normally we're okay for a while. And,
140one nice side effect of \XML\ is that it can't really crash processing as it's
141just data.
142
143\stopsection
144
145\startsection[title=Color fonts]
146
147Then color fonts showed up in \OPENTYPE\ and \SVG\ is one of the used
148sub|-|formats in that. Again it was convenient enough to rely on \INKSCAPE\ to do
149the conversion to \PDF\ blobs, but after a while I decided that a more native
150(built|-|in) support start making sense. A lot had happened since 2000, most
151noticeably the arrival of \LUATEX\ and \CONTEXT\ \MKIV\ followed by \LUAMETATEX\
152and \CONTEXT\ \LMTX, so a more direct support because more feasible. A more
153direct support has the advantage that we don't need to call an external program
154and cache the results (think of Emoji fonts with thousands of glyphs in \SVG\
155format). Also, direct conversion makes it possible to tweak colors and such,
156simply because the data goes through the \CONTEXT\ internals as part of the
157typesetting process. So, as a prelude to the \CONTEXT\ 2019 meeting a preliminary
158converter was made, color font support was partially redone, and afterward the
159converter got completed to the level needed for embedding more fancy graphics,
160including relabeling.
161
162\stopsection
163
164\startsection[title=In practice]
165
166In the end all is about paths or glyphs, plus some optional clipping and
167transformations. The rendering is controlled by attributes: color, transparency,
168line thickness, the way lines join and end, etc. Now, in the original
169specification that was done only with attributes, which is a clean and robust way
170of doing it, but later styles and classes were introduced and we now have a whole
171chain to consider when resolving a to be used attribute.
172
173\startitemize[packed]
174    \startitem attributes explicitly set by keys to an element \stopitem
175    \startitem attributes set in the \type {style} attribute \stopitem
176    \startitem attributes set via one or more \type {class} assignments \stopitem
177    \startitem attributes set for the specific element \stopitem
178    \startitem attributes inherited from an ancestor (somewhat vague) \stopitem
179    \startitem redundant (nested) attributes (text styling) \stopitem
180\stopitemize
181
182Where examples are often hand codes and therefore look ok, graphics that get
183generated can look quite horrible: the same parameters being set with different
184methods, even inconsistently, to mention one. But also, graphics can be read in,
185tweaked and saved again which in itself generates artifacts, etc. One can of
186course argue that \XML\ is not for human consumption but personally I tend to
187conclude that when a source file looks bad, the likelyhood is great that what it
188encodes looks bad too. And for instance \INKSCAPE\ provides ways to inspect and
189tweak the \XML\ in the editor.
190
191\stopsection
192
193\startsection[title=The conversion]
194
195This brings us to the conversion. As we need \PDF\ operators one method is to
196directly go from \SVG\ to \PDF. There is the issue of fonts, but as we delegate
197that to \TEX\ anyway, because that is kind of an abstraction. Such a conversion
198is comparable with going from \METAPOST\ to \PDF. However, for practical reasons
199an intermediate step has been chosen: we go from \SVG\ to \METAPOST\ first. This
200has the benefit that we need little code for color and transparency because
201\METAPOST\ (read: \METAFUN) already deals with that. We also don't need that much
202for text, as we deal with that in \METAPOST\ too, and that way we can even
203overload and reposition for instance labels in graphics relatively easy.
204
205Another advantage of the intermediate step is that we can combine \SVG\ graphics
206with \METAPOST\ code. Of course we can already combine external graphics with
207\METAPOST, but there is a big advantage here: the output is quite efficient. When
208we transform paths and pens in \METAPOST, the end result is often just a path,
209but where we to do a direct conversion to \PDF, we would either have to do
210calculations on our own, or we would have to use lots of transformation
211directives. In the end, especially because \METAPOST\ is so fast, the indirect
212route pays of well (and I haven't even optimized it yet).
213
214\stopsection
215
216\startsection[title=Remark]
217
218In the perspective if using \TEX\ and \METAPOST\ it makes sense to keep an eye on
219consistency. You can make quite structured \SVG\ images if you want to. When you
220use a graphical editor you can even consider using a normal text editor to clean
221up the code occasionally. The cleaner the code, the more predictable the outcome
222will become. Looking at the code might also give an impression of what features
223not to use of use differently. Of course this makes most sense in situations
224where there are many graphics and long|-|term (re)use is needed.
225
226\stopsection
227
228\stoptitle
229
230\starttitle[title=Embedding graphics]
231
232\startsection[title=External figures]
233
234At least for now, the default \SVG\ inclusions is done via an external converter
235but you can use the internal one by specifying a conversion. The next example
236demonstrates that it works like any external figure:
237
238\startbuffer
239\startcombination[4*1]
240    {\externalfigure[mozilla-tiger.svg][conversion=mp]}                      {1}
241    {\externalfigure[mozilla-tiger.svg][conversion=mp,height=1cm]}           {2}
242    {\externalfigure[mozilla-tiger.svg][conversion=mp,height=3cm,width=1cm]} {3}
243    {\externalfigure[mozilla-tiger.svg][conversion=mp,height=1cm,width=8cm]} {4}
244\stopcombination
245\stopbuffer
246
247\typebuffer[option=TEX]
248
249We get:
250
251\startlinecorrection
252    \getbuffer
253\stoplinecorrection
254
255\stopsection
256
257\startsection[title=Internal figures]
258
259You can put some \SVG\ code in a buffer:
260
261\startbuffer
262\startbuffer[svgtest]
263    <svg>
264        <rect
265            x="0" y="0" width="80" height="20"
266            fill="blue" stroke="red" stroke-width="3"
267            stroke-linejoin="miter"
268            transform="rotate(10)"
269        />
270    </svg>
271\stopbuffer
272\stopbuffer
273
274\typebuffer[option=TEX] \getbuffer
275
276In the future more options might be added but for now there's only an offset
277possible:
278
279\startbuffer
280\startcombination[2*1]
281    {\framed[offset=overlay]{\includesvgbuffer[svgtest]}}             {default}
282    {\framed[offset=overlay]{\includesvgbuffer[svgtest][offset=2bp]}} {some offset}
283\stopcombination
284\stopbuffer
285
286\typebuffer[option=TEX] \getbuffer
287
288There is a companion command \type {\includesvgfile} which accepts a filename
289and also supports offsets. Sometimes the offset is needed to prevent unwanted
290clipping.
291
292\stopsection
293
294\startsection[title=Mixing in \METAFUN]
295
296An \SVG\ image can be directly included in an \METAFUN\ image. This makes it
297possible to enhance (or manipulate) such an image, as in:
298
299\startbuffer
300\startMPcode
301    draw lmt_svg [
302        filename = "mozilla-tiger.svg",
303        origin   = true,
304    ] rotated 45 slanted .75 ysized 2cm ;
305
306    setbounds currentpicture to
307        boundingbox currentpicture
308        enlarged 1mm ;
309
310    addbackground
311        withcolor "darkgray" ;
312\stopMPcode
313\stopbuffer
314
315\typebuffer[option=TEX]
316
317An \SVG\ image included this way becomes a regular \METAPOST\ picture, so a
318collection of paths. Because \METAPOST\ on the average produces rather compact
319output the \SVG\ image normally also is efficiently embedded. You don't need to
320worry about loosing quality, because \METAPOST\ is quite accurate and we use so
321called \quote {double} number mode anyway.
322
323\startlinecorrection
324    \getbuffer
325\stoplinecorrection
326
327Another trick is to inline the code:
328
329\startbuffer
330\startMPcode
331    draw svg "<svg>
332        <circle
333            cx='50' cy='50' r='40'
334            stroke='green' stroke-width='10' stroke-opacity='0.3'
335            fill='red' fill-opacity='0.3'
336        />
337        <circle
338            cx='150' cy='50' r='40'
339            stroke='green' stroke-width='10'
340            fill='red'
341            opacity='0.3'
342        />
343    </svg>" ;
344\stopMPcode
345\stopbuffer
346
347It doesn't really make sense as \METAPOST\ code is just as simple but
348it looks cool:
349
350\startlinecorrection
351    \getbuffer
352\stoplinecorrection
353
354And actually it's less code (which internally of course expands to
355more):
356
357\startbuffer
358\startMPcode
359    pickup pencircle scaled 10;
360    path p ; p := fullcircle scaled 80 ;
361    fill p shifted (50,50) withcolor blue
362        withtransparency(1,0.3) ;
363    draw p shifted (50,50) withcolor yellow
364        withtransparency(1,0.3) ;
365    draw image (
366        fill p shifted (150,50) withcolor blue ;
367        draw p shifted (150,50) withcolor yellow ;
368        setgroup currentpicture to boundingbox currentpicture
369            withtransparency(1,0.3) ;
370    ) ;
371\stopMPcode
372\stopbuffer
373
374\typebuffer[option=TEX]
375
376It's all a matter of taste. Watch the grouping trick!
377
378\startlinecorrection
379    \getbuffer
380\stoplinecorrection
381
382\stopsection
383
384\startsection[title=Fonts]
385
386{\em This is still experimental.}
387
388\stopsection
389
390\startsection[title=Labels]
391
392{\em This is still experimental.}
393
394\stopsection
395
396\startsection[title=Tracing]
397
398{\em This is still experimental.}
399
400\stopsection
401
402\stoptitle
403
404\starttitle[title=Mozilla test snippets]
405
406The Mozilla documentation pages for \SVG\ are pretty good and contain snippets
407that can be used for testing. More examples might be added in due time.
408
409\dorecurse{38}{
410    \page
411    \startsection[title=Snippet #1]
412        \framed
413          [offset=overlay]
414          {\scale[height=4cm]{\showSVGcode{svg-lmtx-mozilla.lua}{#1}}}
415        \blank
416        \start
417            \switchtobodyfont[10pt]
418            \setupalign[flushleft,verytolerant,broad]
419            \typeSVGcode{svg-lmtx-mozilla.lua}{#1}
420            \par
421        \stop
422    \stopsection
423    \page
424}
425
426\stoptitle
427
428\starttitle[title=Microsoft test snippets]
429
430These snippets come from the \MICROSOFT\ typography pages that discuss \OPENTYPE\
431and \SVG. Because these are actually examples of glyphs, we need to set some
432defaults:
433
434\starttabulate[|cT|rT|]
435\NC x      \NC    0 \NC \NR
436\NC y      \NC 1000 \NC \NR
437\NC width  \NC 1000 \NC \NR
438\NC height \NC 1000 \NC \NR
439\stoptabulate
440
441in order to get the right placement. This has to do with the fact that the
442vertical \SVG\ coordinates go in the other direction compared to \METAPOST\ and
443\PDF.
444
445\dorecurse{8}{
446    \page
447    \startsection[title=Snippet #1]
448        \framed
449          [offset=overlay]
450          {\scale[height=4cm]{\showSVGcodeG{svg-lmtx-microsoft.lua}{#1}}}
451        \blank
452        \start
453            \switchtobodyfont[10pt]
454            \setupalign[flushleft,verytolerant,broad]
455            \typeSVGcode{svg-lmtx-microsoft.lua}{#1}
456            \par
457        \stop
458        \page
459    \stopsection
460    \page
461}
462
463\stoptitle
464
465\starttitle[title=Xah Lee test snippets]
466
467These snippets come from the \type {http://xahlee.info/js/svg_path_spec.html},
468which gives a nice overview of \SVG. Not all examples are here. There are some
469nice interactive examples there plus info about using fonts.
470
471\dorecurse{38}{
472    \page
473    \startsection[title=Snippet #1]
474        \framed
475          [offset=overlay]
476          {\scale[height=4cm]{\showSVGcodeG{svg-lmtx-xahlee.lua}{#1}}}
477        \blank
478        \start
479            \switchtobodyfont[10pt]
480            \setupalign[flushleft,verytolerant,broad]
481            \typeSVGcode{svg-lmtx-xahlee.lua}{#1}
482            \par
483        \stop
484        \page
485    \stopsection
486    \page
487}
488
489\stoptitle
490
491\starttitle[title=Our own snippets]
492
493These snippets were made as part if testing. I had some 1500 \SVG\ graphics that
494internally were quite messy (it's surprising what some applications export) so I
495sometimes had to extract bits and pieces and make my own tests to figure out how
496to deal with it.
497
498\dorecurse{2}{
499    \page
500    \startsection[title=Snippet #1]
501        \framed
502          [offset=overlay]
503          {\scale[height=4cm]{\showSVGcode{svg-lmtx-context.lua}{#1}}}
504        \blank
505        \start
506            \switchtobodyfont[10pt]
507            \setupalign[flushleft,verytolerant,broad]
508            \typeSVGcode{svg-lmtx-context.lua}{#1}
509            \par
510        \stop
511        \page
512    \stopsection
513    \page
514}
515
516\stoptitle
517
518\stoptext
519
520% After some contemplating, while listening to Benmont Tench's solo album (2014),
521% after first listening to a nice long interview, which I hit after following some
522% Hammond links, I finally decided that it made sense to write this manual. Life is
523% too short for delays.
524