-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathspecification.tex
1354 lines (1091 loc) · 54 KB
/
specification.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% Options for packages loaded elsewhere
\PassOptionsToPackage{unicode}{hyperref}
\PassOptionsToPackage{hyphens}{url}
%
\documentclass[]{article}
\usepackage[a4paper, margin=1in]{geometry}
% \author{}
% \date{}
\usepackage{amsmath,amssymb}
\usepackage{lmodern}
\usepackage{iftex}
\ifPDFTeX
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
\else % if luatex or xetex
\usepackage{unicode-math}
\defaultfontfeatures{Scale=MatchLowercase}
\defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
\fi
% Use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\IfFileExists{microtype.sty}{% use microtype if available
\usepackage[]{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\makeatletter
\@ifundefined{KOMAClassName}{% if non-KOMA class
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
\KOMAoptions{parskip=half}}
\makeatother
\usepackage{xcolor}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{
hidelinks,
pdfcreator={LaTeX via pandoc}}
\urlstyle{same} % disable monospaced font for URLs
\usepackage{color}
\usepackage{fancyvrb}
\newcommand{\VerbBar}{|}
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
% Add ',fontsize=\small' for more characters per line
\newenvironment{Shaded}{}{}
\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}}
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
\newcommand{\BuiltInTok}[1]{#1}
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}}
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}}
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}}
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}}
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}
\newcommand{\ExtensionTok}[1]{#1}
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}}
\newcommand{\ImportTok}[1]{#1}
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}
\newcommand{\NormalTok}[1]{#1}
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}}
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}}
\newcommand{\RegionMarkerTok}[1]{#1}
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}}
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}}
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
\usepackage{longtable,booktabs,array}
\usepackage{calc} % for calculating minipage widths
% Correct order of tables after \subsubsection or \subparagraph
\usepackage{etoolbox}
\makeatletter
\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
\makeatother
% Allow footnotes in longtable head/foot
\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}}
\makesavenoteenv{longtable}
\usepackage{graphicx}
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
\makeatother
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
% Set default figure placement to htbp
\makeatletter
\def\fps@figure{htbp}
\makeatother
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
\ifLuaTeX
\usepackage{selnolig} % disable illegal ligatures
\fi
%
% ↑
% stuff above this was defined by pandoc
% stuff below this was changed by humans
% ↓
%
\usepackage{listings}
\usepackage{courier}
\lstset{basicstyle=\footnotesize\ttfamily}
\newcommand{\link}[2]{\hyperlink{#1}{\emph{#2}}}
\begin{document}
\begin{titlepage}
\begin{center}
\vspace*{1cm}
\includegraphics[height=20cm]{design/logo.pdf}
\vspace*{1cm}
\Huge Specification\\
\vspace{0.5cm}
\LARGE (Working Draft)
\vfill
\begin{abstract}
\Large
The tiny vector graphics format is a binary file
format that encodes a list of vector graphic primitives. It is tailored
to have a tiny memory footprint and simple implementations, while
lifting small file size over encoding simplicity.
\end{abstract}
\vspace{0.8cm}
\end{center}
\end{titlepage}
\hypertarget{introduction}{\section{Introduction}\label{introduction}}
\hypertarget{why-a-new-format}{\subsection{Why a new format}\label{why-a-new-format}}
SVG is the status quo widespread vector format. Every program can kinda
use it and can probably render it right to some extent. The problem is
that SVG is a horribly large specification, it is based on XML and
provides not only vector graphics, but also a full suite for animation
and JavaScript scripting. Implementing a new SVG renderer from scratch
is a tremendous amount of work, and it is hard to get it done right.
Quoting the \href{https://de.wikipedia.org/wiki/Scalable_Vector_Graphics}{german Wikipedia}:
\begin{quote}
Praktisch alle relevanten Webbrowser können einen Großteil des
Sprachumfangs darstellen.\\
Virtually all relevant web browsers can display a large part of the
language range.
\end{quote}
The use of XML bloats the files by a huge magnitude and doesn't provide
an efficient encoding, thus a lot of websites and applications ship files
that are not encoded optimally. Also, SVG allows several ways of
achieving the same thing, and can be seen more as an intermediate format
for editing as for final encoding.
TinyVG was created to address most of these problems, trying to achieve a
balance between flexibility and file size, while keeping file size as
the more important priority.
\hypertarget{features}{\subsection{Features}\label{features}}
\begin{itemize}
\tightlist
\item Binary encoding
\item
Support of the most common 2D vector primitives
\begin{itemize}
\tightlist
\item Paths
\item Polygons
\item Rectangles
\item Lines
\end{itemize}
\item
3 different fill styles
\begin{itemize}
\tightlist
\item Flat color
\item Linear 2-point gradient
\item Radial 2-point gradient
\end{itemize}
\item Dense encoding, there are near zero padding bits and every byte is used as good as possible.
\end{itemize}
\hypertarget{recognition}{\section{Recognizing TinyVG}\label{recognition}}
TinyVG is using the \texttt{.tvg} file extension and should use the \texttt{image/tinyvg} mime type.
The textual representation should use the \texttt{.tvgt} file extension and the \texttt{text/tinyvg} mime type.
\hypertarget{display-units}{\section{Display Units}\label{display-units}}
Contrary to pixel graphics, vector graphics don't have a inherent unit system. While pixels in a bitmap map 1:1 to pixels on a screen, a vector graphic unit does not have this requirement.
TinyVG uses an abstract unit called \emph{display unit} which is defined to be a 1/96th of an inch. This matches the CSS pixel definition so a TinyVG graphic with 48x48 display units will match a typical 48x48 bitmap.
\hypertarget{coordinate-system}{\section{Coordinate system}\label{coordinate-system}}
TinyVG uses the 2-dimensional \href{https://en.wikipedia.org/wiki/Cartesian_coordinate_system}{Cartesian
coordinate system} with X being the positive horizontal distance to the
origin and Y being the negative vertical distance to the origin. This
means that X is going right, while Y is going down, to match the
coordinate system of several other image formats:
\begin{center}
\includegraphics[width=0.5\textwidth]{graphics/coordinates.pdf}
\end{center}
\hypertarget{binary-encoding}{\section{Binary Encoding}\label{binary-encoding}}
TinyVG files are roughly structured like this:
\begin{center}
\includegraphics[height=0.35\textwidth]{graphics/overview.pdf}
\end{center}
Files are made up of a header, followed by a color lookup table and a
sequence of commands terminated by a \emph{end of file} command.
Concrete color values will only be present in the color table. After the
table, only indices into the color table are used to define color
values. This allows to keep the format small, as the first 128 colors in
the vector data are encoded as only a single byte, even if the color
format uses 16 bytes per color. This means in the worst case, we add a
single byte to the size of a color that is only used once, but colors
that are common in the file will be encoded as a single byte per use +
one time overhead. This encoding scheme was chosen as a vector graphic
typically doesn't use as many different colors as bitmap graphics and
thus can be encoded more optimally.
\hypertarget{binary-notes}{\subsection{Notes}\label{binary-notes}}
\begin{itemize}
\item The following documentation uses a tabular style to document structures.
\item All integers are assumed to be encoded in little-endian byte order if not specified otherwise.
\item The \emph{Type} column of each structure definition uses a Zig notation for types and the fields
have no padding bits in between. If a field does not align to a byte boundary, the next field will
be offset into the byte by the current fields bit offset + bit size. This means, that two consecutive
fields \textbf{a} (\texttt{u3}) and \textbf{b} (\texttt{u5}) can be extracted from the byte by using
\texttt{(byte\ \&\ 0x7)\ \textgreater{}\textgreater{}\ 0} for \textbf{a} and \texttt{(byte\ \&\ 0xF8)\ \textgreater{}\textgreater{}\ 3}
for \textbf{b}.
\item If not specified otherwise, all coordinates in TinyVG are absolute coordinates, including path nodes and gradients.
\item A lot of encoded integers are encoded off-by-one, thus mapping 0 to 1, 1 to 2 and so on. This is done as encoding these integers as 0 would be equivalent to removing the element from the file. Thus, this can be used to encode some more elements with less bytes. If this is the case, this is signaled by the use of \texttt{\textit{value}+1}.
\end{itemize}
\hypertarget{header}{\subsection{Header}\label{header}}
Each TVG file starts with a header defining some global values for the
file like scale and image size. The header is always at offset 0 in a
file.
\begin{longtable}[]{@{}p{1in}p{1in}p{4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
magic & \texttt{{[}2{]}u8} & Must be \texttt{\{\ 0x72,\ 0x56\ \}} \\
version & \texttt{u8} & Must be \texttt{1}. For future versions, this field might decide how the rest of the format looks like. \\
scale & \texttt{u4} & Defines the number of fraction bits in a \link{units}{\texttt{Unit}} value. \\
color\_encoding & \texttt{u2} & Defines the type of color information that is used in the \link{color-table}{color table}. \\
coordinate\_range & \texttt{u2} & Defines the number of total bits in a \link{units}{\texttt{Unit}} value and thus the overall precision of the file. \\
width & \texttt{u8}, \texttt{u16} or \texttt{u32} & Encodes the maximum width of the output file in \link{display-units}{display units}. A value of 0 indicates that the image has the maximum possible width. The size of this field depends on the coordinate range field. \\
height & \texttt{u8}, \texttt{u16} or \texttt{u32} & Encodes the maximum height of the output file in \link{display-units}{display units}. A value of 0 indicates that the image has the maximum possible height. The size of this field depends on the coordinate range field. \\
color\_count & \texttt{VarUInt} & The number of colors in the \link{color-table}{color table}. \\
\bottomrule
\end{longtable}
\hypertarget{color-encoding}{\subsubsection{Color Encoding}\label{color-encoding}}
The color encoding defines which format the colors in the color table
will have:
\begin{longtable}[]{@{}p{0.5in}p{1in}p{4.5in}@{}}
\toprule
Value & Enumeration & Description \\
\midrule
\endhead
0 & RGBA 8888 & Each color is a 4-tuple (red, green, blue, alpha) of bytes with the color channels encoded in sRGB and the alpha as linear alpha. \\
1 & RGB 565 & Each color is encoded as a 3-tuple (red, green, blue) with 16 bit per color. While red and blue both use 5 bit, the green channel uses 6 bit. red uses bit range 0...4, green bits 5...10 and blue bits 11...15. This color also uses the sRGB color space.\\
2 & RGBA F32 & Each color is a 4-tuple (red, green ,blue, alpha) of binary32 IEEE 754 floating point value with the color channels encoded in scRGB and the alpha as linear alpha. A color value of \texttt{1.0} is full intensity, while a value of \texttt{0.0} is zero intensity. \\
3 & Custom & The custom color encoding is \emph{undefined}. The information how these colors are encoded must be implemented via external means. \\
\bottomrule
\end{longtable}
\hypertarget{coordinate-range}{\subsubsection{Coordinate Range}\label{coordinate-range}}
The coordinate range defines how many bits a
\link{units}{\texttt{Unit}} value uses:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Value & Enumeration & Description \\
\midrule
\endhead
0 & Default & Each \texttt{Unit} takes up 16 bit. \\
1 & Reduced & Each \texttt{Unit} takes up 8 bit. \\
2 & Enhanced & Each \texttt{Unit} takes up 32 bit. \\
\bottomrule
\end{longtable}
\hypertarget{varuint}{\subsubsection{\texorpdfstring{\texttt{VarUInt}}{VarUInt}}\label{varuint}}
This type is used to encode 32 bit unsigned integers while keeping the
number of bytes low. It is encoded as a variable-sized integer that uses
7 bit per byte for integer bits and the 7th bit to encode that there is
"more bits available".
The integer is still built as a little-endian, so the first byte will
always encode bits 0\ldots6, the second one encodes 8\ldots13, and so
on. Bytes are read until the uppermost bit in the byte is not set. The bit
mappings are done as following:
\begin{longtable}[]{@{}p{0.5in}p{0.75in}p{4.75in}@{}}
\toprule
Byte & Bit Range & Notes \\
\midrule
\endhead
\#1 & 0\ldots6 & This byte must always be present. \\
\#2 & 7\ldots13 & \\
\#3 & 14\ldots20 & \\
\#4 & 21\ldots27 & \\
\#5 & 28\ldots31 & This byte must always have the uppermost 4 bits set as \texttt{0b0000????}. \\
\bottomrule
\end{longtable}
So a \texttt{VarUInt} always has between 1 and 5 bytes while mapping the
full range of a 32 bit value. This means we only have 5 bit overhead in
the worst case, but for all smaller values, we reduce the number of
bytes for encoding unsigned integers.
\paragraph{Encoding Examples}
The following table contains some examples on how a \texttt{VarUInt} is encoded as a byte sequence. The byte sequence is written in hexadecimal to allow uniform notation.
\begin{longtable}[]{@{}p{1in}p{5in}@{}}
\toprule
Integer Value & Byte Sequence \\
\midrule
\endhead
0 & \texttt{00} \\
100 & \texttt{64} \\
127 & \texttt{7F} \\
128 & \texttt{80 01} \\
16271 & \texttt{8F 7F} \\
16383 & \texttt{FF 7F} \\
16384 & \texttt{80 80 01} \\
1048576 & \texttt{80 80 40} \\
2097151 & \texttt{FF FF 7F} \\
2097152 & \texttt{80 80 80 01} \\
2147483648 & \texttt{80 80 80 80 08} \\
4294967295 & \texttt{FF FF FF FF 0F } \\
\bottomrule
\end{longtable}
\paragraph{Overlong Encodings}
The above encoding means that there are multiple ways to encode some values, and decoders must be
prepared to handle that.
\begin{longtable}[]{@{}p{1in}p{5in}@{}}
\toprule
Integer Value & Byte Sequence \\
\midrule
\endhead
0 & \texttt{80 80 80 80 00} \\
1 & \texttt{80 80 80 80 01} \\
\bottomrule
\end{longtable}
The maximum length of an encoded value is 5 bytes. Decoders must reject the following values.
\begin{longtable}[]{@{}p{2in}p{4in}@{}}
\toprule
Error Reason & Byte Sequence \\
\midrule
\endhead
Went 5 bytes without ending & \texttt{80 80 80 80 80 00} \\
Encodes a value greater than $2^{32}$ & \texttt{FF FF FF FF 1F} \\
\bottomrule
\end{longtable}
Encoders should encode using the shortest encoding, however.
\hypertarget{example-code}{\subparagraph{Example Code}\label{example-code}}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{fn }\FunctionTok{read}\OperatorTok{()}\NormalTok{ u32 }\OperatorTok{\{}
\DataTypeTok{var}\NormalTok{ count }\OperatorTok{=} \DecValTok{0}\OperatorTok{;}
\DataTypeTok{var}\NormalTok{ result }\OperatorTok{=} \DecValTok{0}\OperatorTok{;}
\KeywordTok{while} \OperatorTok{(}\KeywordTok{true}\OperatorTok{)} \OperatorTok{\{}
\DataTypeTok{const} \DataTypeTok{byte} \OperatorTok{=} \FunctionTok{readByte}\OperatorTok{();}
\DataTypeTok{const}\NormalTok{ val }\OperatorTok{=} \OperatorTok{(}\DataTypeTok{byte} \OperatorTok{\&} \BaseNTok{0x7F}\OperatorTok{)} \OperatorTok{\textless{}\textless{}} \OperatorTok{(}\DecValTok{7} \OperatorTok{*}\NormalTok{ count}\OperatorTok{);}
\NormalTok{ result }\OperatorTok{|=}\NormalTok{ val}\OperatorTok{;}
\KeywordTok{if} \OperatorTok{((}\DataTypeTok{byte} \OperatorTok{\&} \BaseNTok{0x80}\OperatorTok{)} \OperatorTok{==} \DecValTok{0}\OperatorTok{)}
\KeywordTok{break}\OperatorTok{;}
\NormalTok{ count }\OperatorTok{+=} \DecValTok{1}\OperatorTok{;}
\OperatorTok{\}}
\KeywordTok{return}\NormalTok{ result}\OperatorTok{;}
\OperatorTok{\}}
\NormalTok{fn }\FunctionTok{write}\OperatorTok{(}\NormalTok{value}\OperatorTok{:}\NormalTok{ u32}\OperatorTok{)} \DataTypeTok{void} \OperatorTok{\{}
\DataTypeTok{var}\NormalTok{ iter }\OperatorTok{=}\NormalTok{ value}\OperatorTok{;}
\KeywordTok{while} \OperatorTok{(}\NormalTok{iter }\OperatorTok{\textgreater{}=} \BaseNTok{0x80}\OperatorTok{)} \OperatorTok{\{}
\FunctionTok{writeByte}\OperatorTok{(}\BaseNTok{0x80} \OperatorTok{|} \OperatorTok{(}\NormalTok{iter }\OperatorTok{\&} \BaseNTok{0x7F}\OperatorTok{));}
\NormalTok{ iter }\OperatorTok{\textgreater{}\textgreater{}=} \DecValTok{7}\OperatorTok{;}
\OperatorTok{\}}
\FunctionTok{writeByte}\OperatorTok{(}\NormalTok{iter}\OperatorTok{);}
\OperatorTok{\}}
\end{Highlighting}
\end{Shaded}
\hypertarget{color-table}{\subsection{Color Table}\label{color-table}}
The color table encodes the palette for this file. It's binary content
is defined by the \texttt{color\_encoding} field in the header. For the
three defined color encodings, each will yield a list of
\texttt{color\_count} RGBA tuples.
\hypertarget{rgba-8888}{\subsubsection{RGBA 8888}\label{rgba-8888}}
Each color value is encoded as a sequence of four bytes:
\begin{longtable}[]{@{}p{0.5in}p{0.5in}p{5.0in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
red & \texttt{u8} & Red color channel between 0 and 100\% intensity, mapped to byte values 0 to 255. \\
green & \texttt{u8} & Green color channel between 0 and 100\% intensity, mapped to byte values 0 to 255. \\
blue & \texttt{u8} & Blue color channel between 0 and 100\% intensity, mapped to byte values 0 to 255. \\
alpha & \texttt{u8} & Transparency channel between 0 and 100\% transparency, mapped to byte values 0 to 255. \\
\bottomrule
\end{longtable}
The size of the color table is \texttt{4\ *\ color\_count}.
This color encoding uses the sRGB color space.
\hypertarget{rgb-565}{\subsubsection{RGB 565}\label{rgb-565}}
Each color value is encoded as a sequence of 2 bytes:
\begin{longtable}[]{@{}p{0.5in}p{0.5in}p{5.0in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
red & \texttt{u5} & Red color channel between 0 and 100\% intensity, mapped to integer values 0 to 31. \\
green & \texttt{u6} & Green color channel between 0 and 100\% intensity, mapped to integer values 0 to 63. \\
blue & \texttt{u5} & Blue color channel between 0 and 100\% intensity, mapped to integer values 0 to 31. \\
\bottomrule
\end{longtable}
The size of the color table is \texttt{2\ *\ color\_count}, and all
colors are fully opaque.
This color encoding uses the sRGB color space.
\hypertarget{rgba-f32}{\subsubsection{RGBA F32}\label{rgba-f32}}
Each color value is encoded as a sequence of 16 bytes:
\begin{longtable}[]{@{}p{0.5in}p{0.5in}p{5.0in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
red & \texttt{f32} & Red color channel, using 0.0 for 0\% intensity and 1.0 for 100\% intensity. \\
green & \texttt{f32} & Green color channel, using 0.0 for 0\% intensity and 1.0 for 100\% intensity. \\
blue & \texttt{f32} & Blue color channel, using 0.0 for 0\% intensity and 1.0 for 100\% intensity. \\
alpha & \texttt{f32} & Transparency channel between 0 and 100\% transparency, mapped to byte values 0.0 to 1.0. \\
\bottomrule
\end{longtable}
The size of the color table is \texttt{16\ *\ color\_count}.
This color encoding uses the scRGB color space, so the intensity is allowed to be both negative and positive for a wider color gamut.
\hypertarget{custom}{\subsubsection{Custom}\label{custom}}
The TinyVG specification does not describe the size nor format of this
kind of color table. An implementation specific format is expected. A
conforming parser is allowed to reject files with this color format as
"unsupported".
\hypertarget{commands}{\subsection{Commands}\label{commands}}
TinyVG files contain a sequence of draw commands that must be executed
in the defined order to get the final result. Each draw command adds a
new 2D primitive to the graphic.
The following commands are available:
\begin{longtable}[]{@{}p{0.5in}p{1.25in}p{4.25in}@{}}
\toprule
Index & Name & Short description \\
\midrule
\endhead
0 & end of document & This command determines the end of file. \\
1 & fill polygon & This command fills an N-gon. \\
2 & fill rectangles & This command fills a set of rectangles. \\
3 & fill path & This command fills a free-form path. \\
4 & draw lines & This command draws a set of lines. \\
5 & draw line loop & This command draws the outline of a polygon. \\
6 & draw line strip & This command draws a list of end-to-end lines. \\
7 & draw line path & This command draws a free-form path. \\
8 & outline fill polygon & This command draws a filled polygon with an outline. \\
9 & outline fill rectangles & This command draws several filled rectangles with an outline. \\
10 & outline fill path & This command combines the fill and draw line path command into one. \\
11 & text hint path & This command defines the contents and glyph location for text \\
\bottomrule
\end{longtable}
Each command is encoded as a single byte which is split into fields:
\begin{longtable}[]{@{}p{1.5in}p{0.5in}p{4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
command\_index & \texttt{u6} & The command that is encoded next. See table above. \\
prim\_style\_kind & \texttt{u2} & The type of style this command uses as a primary style. \\
\bottomrule
\end{longtable}
\hypertarget{end-of-document}{\subsubsection{End Of Document}\label{end-of-document}}
If this command is read, the TinyVG file has ended. This command must
have \texttt{prim\_style\_kind} to be set to 0, so the last byte of
every TinyVG file is \texttt{0x00}.
Every byte after this command is considered not part of the TinyVG data
and can be used for other purposes like metadata or similar.
\hypertarget{fill-polygon}{\subsubsection{Fill Polygon}\label{fill-polygon}}
Fills a \href{https://en.wikipedia.org/wiki/Polygon}{polygon} with N points.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
point\_count & \link{varuint}{\texttt{VarUInt}} & The number of points in the polygon. This value is offset by 1. \\
fill\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to fill the polygon.\\
polygon & \texttt{{[}point\_count+1{]}Point} & The points of the polygon. \\
\bottomrule
\end{longtable}
The offset in \texttt{point\_count} is there due to 0 points not making
any sense at all, and the command could just be skipped instead of encoding
it with 0 points. The offset is 1 to allow code sharing between other
fill commands, as each fill command shares the same header.
\texttt{point\_count} must be at least 2, files that encode a lower
value must be discarded as "invalid" by a conforming implementation.
The polygon specified in \texttt{polygon} must be drawn using the
\href{https://en.wikipedia.org/wiki/Even\%E2\%80\%93odd_rule}{even-odd
rule}, that means that if for any point to be inside the polygon, a line
to infinity must cross an odd number of polygon segments.
\begin{center}
\includegraphics{graphics/fill-polygon.pdf}
\end{center}
\hypertarget{point}{\subparagraph{\texorpdfstring{\texttt{Point}}{Point}}\label{point}}
Points are a X and Y coordinate pair:
\begin{longtable}[]{@{}p{1in}p{1in}p{4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
x & \link{units}{\texttt{Unit}} & Horizontal distance of the point to the origin. \\
y & \link{units}{\texttt{Unit}} & Vertical distance of the point to the origin. \\
\bottomrule
\end{longtable}
\hypertarget{units}{\subparagraph{Units}\label{units}}
The unit is the common type for both positions and sizes in the vector
graphic. It is encoded as a signed integer with a configurable amount of
bits (see \link{coordinate-range}{Coordinate Range}) and
fractional bits.
The file header defines a \emph{scale} by which each signed integer is
divided into the final value. For example, with a \emph{reduced} value
of \texttt{0x13} and a scale of \texttt{4}, we get the final value of
1.1875, as the number is interpretet as binary \texttt{b0001.0011}.
\hypertarget{fill-rectangles}{\subsubsection{Fill Rectangles}\label{fill-rectangles}}
Fills a list of rectangles.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
rectangle\_count & \link{varuint}{\texttt{VarUInt}} & The number of rectangles. This value is offset by 1. \\
fill\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to fill all rectangles. \\
rectangles & \texttt{{[}rectangle\_count+1{]}Rectangle} & The list of rectangles to be filled. \\
\bottomrule
\end{longtable}
The offset in \texttt{rectangle\_count} is there due to 0 rectangles not
making any sense at all, and the command could just be skipped instead of
encoding it with 0 rectangles. The offset is 1 to allow code sharing
between other fill commands, as each fill command shares the same
header.
The rectangles must be drawn first to last, which is the order they appear
in the file.
\begin{center}
\includegraphics{graphics/fill-rectangles.pdf}
\end{center}
\hypertarget{rectangle}{\subparagraph{\texorpdfstring{\texttt{Rectangle}}{Rectangle}}\label{rectangle}}
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
x & \link{units}{\texttt{Unit}} & Horizontal distance of the left side to the origin. \\
y & \link{units}{\texttt{Unit}} & Vertical distance of the upper side to the origin. \\
width & \link{units}{\texttt{Unit}} & Horizontal extent of the rectangle. \\
height & \link{units}{\texttt{Unit}} & Vertical extent of the rectangle origin. \\
\bottomrule
\end{longtable}
\hypertarget{fill-path}{\subsubsection{Fill Path}\label{fill-path}}
Fills a \link{path}{path}. Paths are described further
below in more detail to keep this section short.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
segment\_count & \link{varuint}{\texttt{VarUInt}} & The number of segments in the path. This value is offset by 1. \\
fill\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to fill the path. \\
path & \texttt{Path(segment\_count+1)} & A path with \texttt{segment\_count} segments \\
\bottomrule
\end{longtable}
The offset in \texttt{segment\_count} is there due to 0 segments don't
make sense at all and the command could just be skipped instead of
encoding it with 0 segments. The offset is 1 to allow code sharing
between other fill commands, as each fill command shares the same
header.
For the filling, all path segments are considered a polygon each (drawn
with even-odd rule) that, when overlap, also perform the even odd rule.
This allows the user to carve out parts of the path and create
arbitrarily shaped surfaces.
\hypertarget{draw-lines}{\subsubsection{Draw Lines}\label{draw-lines}}
Draws a set of lines.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
line\_count & \link{varuint}{\texttt{VarUInt}} & The number of rectangles. This value is offset by 1. \\
line\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to draw the all rectangles. \\
line\_width & \texttt{Unit} & The width of the line. \\
lines & \texttt{{[}line\_count\ +\ 1{]}Line} & The list of lines. \\
\bottomrule
\end{longtable}
Draws \texttt{line\_count} + 1 lines with \texttt{line\_style}. Each line is \texttt{line\_width} units wide, and at least a single display pixel. This means that \texttt{line\_width} of 0 is still visible, even though only marginally. This allows very thin outlines.
\begin{center}
\includegraphics{graphics/draw-lines.pdf}
\end{center}
\hypertarget{line}{\subparagraph{\texorpdfstring{\texttt{Line}}{Line}}\label{line}}
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
start & \link{point}{\texttt{Point}} & Start point of the line \\
end & \link{point}{\texttt{Point}} & End point of the line. \\
\bottomrule
\end{longtable}
\hypertarget{draw-line-loop}{\subsubsection{Draw Line Loop}\label{draw-line-loop}}
Draws a polygon.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
point\_count & \link{varuint}{\texttt{VarUInt}} & The number of points. This value is offset by 1. \\
line\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to draw the all rectangles. \\
line\_width & \texttt{Unit} & The width of the line. \\
points & \texttt{{[}point\_count\ +\ 1{]}Point} & The points of the polygon. \\
\bottomrule
\end{longtable}
Draws \texttt{point\_count} + 1 lines with \texttt{line\_style}. Each
line is \texttt{line\_width} units wide.
The lines are drawn between consecutive points as well as the first and
the last point.
\begin{center}
\includegraphics{graphics/draw-line-loop.pdf}
\end{center}
\hypertarget{draw-line-strip}{\subsubsection{Draw Line Strip}\label{draw-line-strip}}
Draws a list of consecutive lines.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
point\_count & \link{varuint}{\texttt{VarUInt}} & The number of points. This value is offset by 1. \\
line\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to draw the all rectangles. \\
line\_width & \texttt{Unit} & The width of the line. \\
points & \texttt{{[}point\_count\ +\ 1{]}Point} & The points of the line strip. \\
\bottomrule
\end{longtable}
Draws \texttt{point\_count} + 1 lines with \texttt{line\_style}.
The lines are drawn between consecutive points, but contrary to \emph{Draw Line Loop}, the first and the last point are not connected.
\begin{center}
\includegraphics{graphics/draw-line-strip.pdf}
\end{center}
\hypertarget{draw-line-path}{\subsubsection{Draw Line Path}\label{draw-line-path}}
Draws a \link{path}{path}. Paths are described further
below in more detail to keep this section short.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
segment\_count & \link{varuint}{\texttt{VarUInt}} & The number of segments in the path. This value is offset by 1. \\
line\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to draw the all rectangles. \\
line\_width & \texttt{Unit} & The width of the line. \\
path & \texttt{Path(segment\_count\ +\ 1)} & A path with \texttt{segment\_count} segments. \\
\bottomrule
\end{longtable}
The outline of the path is \texttt{line\_width} units wide.
\hypertarget{outline-fill-polygon}{\subsubsection{Outline Fill Polygon}\label{outline-fill-polygon}}
Fills a polygon and draws an outline at the same time.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2in}p{3in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
point\_count & \texttt{u6} & The number of points in the polygon. This value is offset by 1. \\
sec\_style\_kind & \texttt{u2} & The secondary style used in this command. \\
fill\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to fill the polygon. \\
line\_style & \texttt{Style(sec\_style\_kind)} & The style that is used to draw the outline of the polygon. \\
line\_width & \texttt{Unit} & The width of the line. \\
points & \texttt{{[}point\_count+1{]}Point} & The set of points of this polygon. \\
\bottomrule
\end{longtable}
This command is a combination of \emph{Fill Polygon} and \emph{Draw Line Loop}. It first performs a \emph{Fill Polygon} with the \texttt{fill\_style}, then performs \emph{Draw Line Loop} with \texttt{line\_style} and \texttt{line\_width}.
\begin{center}
\includegraphics{graphics/outline-polgon.pdf}
\end{center}
The outline commands use a reduced number of elements, the maximum
number of points is 64.
\hypertarget{outline-fill-rectangles}{\subsubsection{Outline Fill Rectangles}\label{outline-fill-rectangles}}
Fills and outlines a list of rectangles.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{2.2in}p{2.8in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
rect\_count & \texttt{u6} & The number of rectangles. This value is offset by 1. \\
sec\_style\_kind & \texttt{u2} & The secondary style used in this command. \\
fill\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to fill the polygon. \\
line\_style & \texttt{Style(sec\_style\_kind)} & The style that is used to draw the outline of the polygon. \\
line\_width & \texttt{Unit} & The width of the line. \\
rectangles & \texttt{{[}rect\_count+1{]}Rectangle} & The list of rectangles to be drawn. \\
\bottomrule
\end{longtable}
For each rectangle, it is first filled, then its outline is drawn, then
the next rectangle is drawn. This allows to overlap rectangles to look
like this:
\begin{center}
\includegraphics{graphics/outline-rectangles.pdf}
\end{center}
The outline commands use a reduced number of elements, the maximum
number of points is 64.
\hypertarget{outline-fill-path}{\subsubsection{Outline Fill Path}\label{outline-fill-path}}
Fills a path and draws an outline at the same time.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{1.6in}p{3.4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
segment\_count & \texttt{u6} & The number of points in the polygon. This value is offset by 1. \\
sec\_style\_kind & \texttt{u2} & The secondary style used in this command. \\
fill\_style & \texttt{Style(prim\_style\_kind)} & The style that is used to fill the polygon. \\
line\_style & \texttt{Style(sec\_style\_kind)} & The style that is used to draw the outline of the polygon. \\
line\_width & \texttt{Unit} & The width of the line. \\
path & \texttt{Path(segment\_count+1)} & The path that should be drawn. \\
\bottomrule
\end{longtable}
This command is a combination of \emph{Fill Path} and \emph{Draw Line Path}.
It first performs a \emph{Fill Path} with the \texttt{fill\_style}, then
performs \emph{Draw Line Path} with \texttt{line\_style} and
\texttt{line\_width}.
The outline commands use a reduced number of elements, the maximum
number of points is 64.
\hypertarget{text-hint}{\subsubsection{Text Hint}\label{text-hint}}
Defines the metadata for rendered text.
The command is structured like this:
\begin{longtable}[]{@{}p{1in}p{1.6in}p{3.4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
center & \texttt{Point} & The center of the descender line for the defined text. \\
rotation & \texttt{Unit} & The amount of degrees the text is rotated. \\
height & \texttt{Unit} & The font size or distance from the ascender line to the descender line for the text. \\
text\_length & \texttt{VarUInt} & The number of bytes used to encode the text. \\
text & \texttt{{[}text\_length{]}u8} & The UTF-8 encoded bytes corresponding to the text. \\
glyph\_length & \texttt{VarUInt} & The number of glyphs within the text. \\
glyph\_offset & \texttt{{[}glyph\_length{]}{[}2{]}Unit} & The start and end offset on the descender line from the center for each glyph. \\
\bottomrule
\end{longtable}
This command only provides metadata for accessibility or text selection tools
for the position and content of text. A renderer can safely ignore this command
since it must not have any effect on the resulting graphic.
\hypertarget{stylestyle_type}{\subsection{\texorpdfstring{\texttt{Style(style\_type)}}{Style(style\_type)}}\label{stylestyle_type}}
There are three types of style available:
\begin{longtable}[]{@{}p{0.5in}p{1in}p{4.5in}@{}}
\toprule
Value & Style Type & Description \\
\midrule
\endhead
0 & Flat Colored & The shape is uniformly colored with a single
color. \\
1 & Linear Gradient & The shape is colored with a linear gradient. \\
2 & Radial Gradient & The shape is colored with a radial gradient. \\
\bottomrule
\end{longtable}
Left to right the three gradient types:
\begin{center}
\includegraphics{graphics/gradients.png}
\end{center}
\hypertarget{flat-colored}{\subsubsection{Flat Colored}\label{flat-colored}}
\begin{longtable}[]{@{}p{1in}p{1in}p{4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
color\_index & \texttt{VarUInt} & The index into the color table \\
\bottomrule
\end{longtable}
The shape is uniformly colored with the color at \texttt{color\_index}
in the color table.
\hypertarget{linear-gradient}{\subsubsection{Linear Gradient}\label{linear-gradient}}
\begin{longtable}[]{@{}p{1in}p{1in}p{4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
point\_0 & \texttt{Point} & The start point of the gradient. \\
point\_1 & \texttt{Point} & The end point of the gradient. \\
color\_index\_0 & \texttt{VarUInt} & The color at \texttt{point\_0}. \\
color\_index\_1 & \texttt{VarUInt} & The color at \texttt{point\_1}. \\
\bottomrule
\end{longtable}
The gradient is formed by a mental line between \texttt{point\_0} and
\texttt{point\_1}. The color at \texttt{point\_0} is the color at
\texttt{color\_index\_0} in the color table, the color at
\texttt{point\_1} is the color at \texttt{color\_index\_1} in the color
table.
On the line, the color is interpolated between the two points.
Each point that is not on the line is orthogonally projected to the line
and the color at that point is sampled. Points that are not projectable
onto the line have either the color at \texttt{point\_0} if they are
closed to \texttt{point\_0} or vice versa for \texttt{point\_1}.
See the \hypertarget{color-interpolation}{Color Interpolation} chapter on how to perform the color interpolation in detail.
\hypertarget{radial-gradient}{\subsubsection{Radial Gradient}\label{radial-gradient}}
\begin{longtable}[]{@{}p{1in}p{1in}p{4in}@{}}
\toprule
Field & Type & Description \\
\midrule
\endhead
point\_0 & \texttt{Point} & The start point of the gradient. \\
point\_1 & \texttt{Point} & The end point of the gradient. \\
color\_index\_0 & \texttt{VarUInt} & The color at \texttt{point\_0}. \\
color\_index\_1 & \texttt{VarUInt} & The color at \texttt{point\_1}. \\
\bottomrule
\end{longtable}
The gradient is formed by a mental circle with the center at
\texttt{point\_0} and \texttt{point\_1} being somewhere on the circle