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