├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── nightly.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── benchmark ├── bench-from-svg.sh ├── benchmark-folder.sh ├── index.htm.foot ├── index.htm.head ├── run-all.sh ├── svgo.config.js └── w3c-files.pdf ├── build-sdk.sh ├── build-spec.sh ├── build.zig ├── design ├── README.md ├── logo.png ├── logo.svg ├── logo.tvg ├── logo.tvgt ├── render.sh ├── social-media-preview.png ├── social-media-preview.xcf └── svgo.config.js ├── documents ├── .gitignore ├── graphics │ ├── coordinates.svg │ ├── gradients.svg │ ├── gradients.tvgt │ ├── outline-polgon.svg │ ├── outline-polygon.tvgt │ ├── outline-rectangles.svg │ ├── outline-rectangles.tvgt │ ├── overview.svg │ └── overview.uxf ├── helper │ ├── runnings.js │ └── style.css ├── sdk-readme.txt ├── specification.md ├── text-format.md └── tvg.ksy ├── examples ├── native │ └── usage.c ├── tinyvg │ ├── .gitignore │ ├── README.md │ ├── everything-32.png │ ├── everything-32.tvg │ ├── everything-32.tvgt │ ├── everything.copy.tvgt │ ├── everything.png │ ├── everything.tvg │ ├── everything.tvgt │ ├── shield-16.png │ ├── shield-16.tvg │ ├── shield-16.tvgt │ ├── shield-32.png │ ├── shield-32.tvg │ ├── shield-32.tvgt │ ├── shield-8.png │ ├── shield-8.tvg │ └── shield-8.tvgt └── web │ └── index.htm ├── info.sh ├── info.yaml ├── render-kaitai.sh ├── render.sh ├── specification.pdf ├── src ├── binding │ ├── binding.zig │ └── include │ │ └── tinyvg.h ├── data │ └── ground-truth.zig ├── lib │ ├── builder.zig │ ├── parsing.zig │ ├── rendering.zig │ ├── svg.zig │ ├── text.zig │ └── tinyvg.zig ├── polyfill │ ├── tinyvg.js │ └── tinyvg.zig └── tools │ ├── gen-index.sh │ ├── render.zig │ ├── svg2tvg │ ├── .gitignore │ ├── Makefile │ ├── svg2tvgt.cs │ └── svg2tvgt.csproj │ └── text.zig └── website ├── benchmark.htm ├── benchmark ├── freesvg.csv ├── freesvg.pdf ├── material-design.csv ├── material-design.pdf ├── papirus.csv ├── papirus.pdf ├── w3c.csv ├── w3c.pdf ├── zig.csv └── zig.pdf ├── favicon.ico ├── img ├── app-icon.png ├── app-icon.svg ├── app-icon.tvg ├── app-icon.tvgt ├── chart.png ├── chart.svg ├── chart.tvg ├── chart.tvgt ├── comic.png ├── comic.svg ├── comic.tvg ├── comic.tvgt ├── flowchart.dot ├── flowchart.png ├── flowchart.tvg ├── flowchart.tvgt ├── shield.png ├── shield.tvg ├── shield.tvgt ├── tiger.png ├── tiger.svg ├── tiger.tvg └── tiger.tvgt ├── index.htm ├── logo.svg └── style.css /.gitattributes: -------------------------------------------------------------------------------- 1 | lib/**/* linguist-vendored 2 | documents/* linguist-documentation 3 | *.zig text=auto eol=lf 4 | examples/* linguist-generated -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Verify PR 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | 7 | jobs: 8 | build-linux: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | with: 13 | submodules: 'recursive' 14 | 15 | - name: Install dependencies 16 | run: | 17 | sudo apt-get update 18 | sudo apt-get imagemagick 19 | 20 | - name: Setup Zig 21 | uses: goto-bus-stop/setup-zig@v1 22 | with: 23 | version: master 24 | 25 | - name: Compile 26 | run: zig build install 27 | 28 | - name: Testsuite 29 | run: zig build test 30 | 31 | - name: Generate Test files 32 | run: zig build generate 33 | 34 | build-macos: 35 | runs-on: macos-latest 36 | steps: 37 | - uses: actions/checkout@v2 38 | with: 39 | submodules: 'recursive' 40 | 41 | - name: Setup Zig 42 | uses: goto-bus-stop/setup-zig@v1 43 | with: 44 | version: master 45 | 46 | - name: Compile 47 | run: zig build install -Dweb-example=false 48 | 49 | - name: Testsuite 50 | run: zig build test 51 | 52 | build-windows: 53 | runs-on: windows-latest 54 | steps: 55 | - uses: actions/checkout@v2 56 | with: 57 | submodules: 'recursive' 58 | 59 | - name: Setup Zig 60 | uses: goto-bus-stop/setup-zig@v1 61 | with: 62 | version: master 63 | 64 | - name: Compile 65 | run: zig build install -Dweb-example=false 66 | 67 | - name: Testsuite 68 | run: zig build test 69 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Nightly Build 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | schedule: 7 | - cron: '0 5 * * *' # run at 5 AM UTC 8 | 9 | jobs: 10 | build-linux: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules: 'recursive' 16 | 17 | - name: Install dependencies 18 | run: | 19 | sudo apt-get update 20 | sudo apt-get install \ 21 | imagemagick p7zip-full \ 22 | npm 23 | sudo npm install -g markdown-pdf 24 | - name: Install dotnet sdk 25 | uses: actions/setup-dotnet@v1 26 | with: 27 | dotnet-version: '5.0.x' 28 | 29 | - name: Setup Zig 30 | uses: goto-bus-stop/setup-zig@v1 31 | with: 32 | version: master 33 | 34 | - name: Compile 35 | run: zig build install 36 | 37 | - name: Testsuite 38 | run: zig build test 39 | 40 | - name: Generate Test files 41 | run: zig build generate 42 | 43 | - name: Compile x86_64-windows release 44 | run: | 45 | zig build -Drelease -Dtarget=x86_64-windows --prefix release/x86_64-windows 46 | 47 | - name: Compile x86_64-linux release 48 | run: | 49 | zig build -Drelease -Dtarget=x86_64-linux --prefix release/x86_64-linux 50 | 51 | - name: Compile x86_64-macos release 52 | run: | 53 | zig build -Drelease -Dtarget=x86_64-macos --prefix release/x86_64-macos 54 | 55 | - name: Compile aarch64-linux release 56 | run: | 57 | zig build -Drelease -Dtarget=aarch64-linux --prefix release/aarch64-linux 58 | 59 | - name: Compile aarch64-macos release 60 | run: | 61 | zig build -Drelease -Dtarget=aarch64-macos --prefix release/aarch64-macos 62 | 63 | - name: Compile dotnet tooling 64 | run: | 65 | make -C src/tools/svg2tvg/ publish 66 | 67 | - name: Compile polyfill 68 | run: zig build install -Drelease -Dpolyfill -Dweb-example 69 | 70 | - name: Compile and bundle SDK 71 | run: | 72 | ./build-sdk.sh 73 | 74 | - name: Render Specification 75 | run: | 76 | mkdir -p dist 77 | ./build-spec.sh website/download/specification.pdf 78 | cp documents/specification.md website/download/specification.md 79 | 80 | - name: Pack Downloads Bundles 81 | run: | 82 | mkdir -p dist 83 | 84 | pushd release/x86_64-windows/bin 85 | 7z a ../../../website/download/tvg-x86_64-windows.zip * 86 | popd 87 | 88 | pushd release/x86_64-linux/bin 89 | 7z a ../../../website/download/tvg-x86_64-linux.zip * 90 | popd 91 | 92 | pushd release/x86_64-macos/bin 93 | 7z a ../../../website/download/tvg-x86_64-macos.zip * 94 | popd 95 | 96 | pushd release/aarch64-linux/bin 97 | 7z a ../../../website/download/tvg-aarch64-linux.zip * 98 | popd 99 | 100 | pushd release/aarch64-macos/bin 101 | 7z a ../../../website/download/tvg-aarch64-macos.zip * 102 | popd 103 | 104 | pushd zig-out/www/ 105 | 7z a ../../website/download/tvg-polyfill.zip * 106 | popd 107 | 108 | pushd sdk-release/ 109 | 7z a ../website/download/tinyvg-sdk.zip * 110 | popd 111 | 112 | - name: Compile SDK file listing 113 | run: | 114 | cd website/download 115 | unzip -l tinyvg-sdk.zip > tinyvg-sdk.txt 116 | 117 | - name: Provide polyfill demo 118 | run: | 119 | cp -r zig-out/www website/polyfill 120 | 121 | - name: Copy some files around 122 | run: | 123 | cp -r design/social-media-preview.png website/img/social-media-preview.png 124 | 125 | - name: Deploy to Server 126 | uses: easingthemes/ssh-deploy@v2.1.1 127 | env: 128 | SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_KEY }} 129 | ARGS: '-rltgoDzvO --delete' 130 | SOURCE: 'website/' 131 | REMOTE_HOST: ${{ secrets.DEPLOY_HOST }} 132 | REMOTE_USER: ${{ secrets.DEPLOY_USERNAME }} 133 | TARGET: '/home/${{ secrets.DEPLOY_USERNAME }}/tinyvg' 134 | 135 | build-macos: 136 | runs-on: macos-latest 137 | steps: 138 | - uses: actions/checkout@v2 139 | with: 140 | submodules: 'recursive' 141 | 142 | - name: Setup Zig 143 | uses: goto-bus-stop/setup-zig@v1 144 | with: 145 | version: master 146 | 147 | - name: Compile 148 | run: zig build install -Dweb-example=false 149 | 150 | - name: Testsuite 151 | run: zig build test 152 | 153 | build-windows: 154 | runs-on: windows-latest 155 | steps: 156 | - uses: actions/checkout@v2 157 | with: 158 | submodules: 'recursive' 159 | 160 | - name: Setup Zig 161 | uses: goto-bus-stop/setup-zig@v1 162 | with: 163 | version: master 164 | 165 | - name: Compile 166 | run: zig build install -Dweb-example=false 167 | 168 | - name: Testsuite 169 | run: zig build test 170 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | zig-cache/ 2 | zig-out/ 3 | dev-thingies/ 4 | kcov-output/ 5 | release/ 6 | output.svg 7 | output.tga 8 | # we will construct the SDK in the CI 9 | sdk-release/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/zig-args"] 2 | path = vendor/zig-args 3 | url = https://github.com/MasterQ32/zig-args 4 | [submodule "vendor/parser-toolkit"] 5 | path = vendor/parser-toolkit 6 | url = https://github.com/MasterQ32/parser-toolkit 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Felix Queißner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # THIS REPO IS ARCHIVED. 2 | 3 | ## DEVELOPMENT CONTINUES AT 4 | ## https://github.com/TinyVG/ 5 | 6 | 7 | # `.tvg`: Tiny Vector Graphics 8 | 9 | ![Project Logo](design/logo.svg) A new format for simple vector graphics. 10 | 11 | ## Why? 12 | 13 | Quoting the german Wikipedia on SVG: 14 | 15 | > Praktisch alle relevanten Webbrowser können einen Großteil des Sprachumfangs darstellen. 16 | 17 | Translated: 18 | 19 | > Virtually all relevant web browsers can display most of the language specification. 20 | 21 | SVG is a horribly complex format, allowing the embedding of JavaScript and other features no sane person ever wants to have in their images. Other relevant vector graphics formats do not exist or don't have a documentation or specification (looking at you, [HVIF](https://en.wikipedia.org/wiki/Haiku_Vector_Icon_Format)!). 22 | 23 | This project tries to create and specify a new vector format suitable for: 24 | 25 | - Small and medium icons (think toolbar, buttons, …) 26 | - Low complexity graphics (think graphs, diagrams, …) 27 | - Embedded platforms (low resource requirements) 28 | 29 | ## Project Goals 30 | 31 | Create a vector graphics format that fulfils the following requirements: 32 | 33 | - Binary encoded ✅ 34 | - Small file size (must be smaller than equivalent bitmaps or SVG graphics) ✅ 35 | - Can be rendered without floating point support (suitable for embedded) ✅ 36 | - Can be rendered efficiently with modern GPUs (suitable for PC, games) ✅ 37 | - Supports the following drawing primitives: 38 | - points / circles ✅ 39 | - lines ✅ 40 | - triangles / polygons ✅ 41 | - Support drawing styles 42 | - filled ✅ 43 | - outline ✅ 44 | - filled with outline ✅ 45 | - Support 46 | - flat colors ✅ 47 | - bitmap textures ❌ (won't be included) 48 | - linear gradients ✅ 49 | - line widths ✅ 50 | - Can use hinting to allow really small rendering (16²) ❌ (won't be included due to increased complexity) 51 | 52 | ## Use Cases 53 | 54 | The use cases here are listed to be considered while working on the specification and give the project a shape and boundary: 55 | 56 | - Application Icons (large, fine details) 57 | - Toolbar Icons (small, simple) 58 | - Graphs (large structure, no details, text, think [graphviz](https://graphviz.org/)) 59 | - Diagrams (colored surfaces, text, lines) 60 | - Mangas/Comics (complex shapes, different line thickness) 61 | 62 | ## Project Status 63 | 64 | This project is coming close to finishing _Version 1_ of the format, and the written spec is the last thing missing. 65 | 66 | See the following documents: 67 | 68 | - [Specification](documents/specification.md) 69 | - [Textual Representation](documents/text-format.md) 70 | 71 | See also this image to have a preview of what is already implemented: 72 | 73 | ![Preview](examples/tinyvg/everything.png) 74 | 75 | ### Milestones 76 | 77 | - [x] Create prototype implementation 78 | - [x] Finalize prototype 79 | - [x] Add smaller/bigger colors (16 bit, 30 bit) 80 | - [x] Add color space information (the color space is defined as sRGB) 81 | - [x] Add extended coordinate space (32 bit coordinates) 82 | - [x] Encode primary style in command, reduces command to 63 variants, allows bigger encoding 83 | - [ ] Improve rendering 84 | - [x] Add anti-aliasing 85 | - [x] Add missing line width modifier for path rendering 86 | - [ ] Improve rendering performance 87 | - [x] Move anti-aliased rendering into core library 88 | - [x] Implement textual representation 89 | - [x] Convert to `.tvg` 90 | - [x] Convert to text 91 | - [x] Format text 92 | - [x] Convert to SVG 93 | - [x] Add auxiliary tools 94 | - [x] C Library frontend 95 | - [ ] Build SDK 96 | - [x] Zig package 97 | - [ ] Native packages 98 | - [x] dynamic macOS x86_64, aarch64 99 | - [x] static macOS x86_64, aarch64 100 | - [x] dynamic Windows x86_64 101 | - [ ] static Windows x86_64 (TODO: Linker error with COMDAT when using VS) 102 | - [x] dynamic Linux x86_64, aarch64, arm 103 | - [x] static Linux x86_64, aarch64, arm 104 | - [x] Wasm Polyfill 105 | - [ ] Improve website 106 | - [ ] Add manual to tools 107 | - [x] Add `tiger.tvg` example file 108 | - [x] Add `comic.tvg` example file 109 | - [x] Add `charts.tvg` example file (pie, line and bar chart) 110 | - [x] Add `app-icon.tvg` example file 111 | - [x] Add `graph.tvg` example file 112 | - [ ] Add text file spec/examples 113 | - [x] Fix polyfill (change CI) 114 | - [x] Benchmark Suite 115 | - [x] File Size (SVG vs. TinyVG) 116 | - [ ] Update final benchmark 117 | - [x] Sort github issues 118 | - [ ] Write specification 119 | - [ ] Review specification 120 | - [ ] Release! 121 | - [ ] Lock the specification into _Version 1_. 122 | 123 | ### Future Tasks 124 | 125 | - [ ] Convert from SVG (via external tool) 126 | - [ ] SVG `` 127 | - [ ] (Fill|Draw|Fill Outlined) Ellipse/Circle opcode 128 | - [ ] Smooth Bezier (via mirror behaviour) 129 | - [ ] Inkscape Plugin 130 | - [ ] library/sdk feature: convert TinyVG to draw lists/commands 131 | 132 | ## Resources 133 | 134 | - [CSS Gradients](https://css-tricks.com/css3-gradients/) 135 | - Radial and conic gradients can be used for nice 3D shading 136 | - Previous Work: [TurtleFont](https://github.com/MasterQ32/turtlefont) is a pure line-drawing vector format 137 | - [SVG Path Editor](https://yqnn.github.io/svg-path-editor/), a tool to easily design or inspect SVG paths 138 | -------------------------------------------------------------------------------- /benchmark/bench-from-svg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script performs a basic benchmark to compare SVG and TVG 4 | # 5 | # $1 is the SVG file that will be rendered to TVG, then back to SVG 6 | 7 | set -eo pipefail 8 | 9 | function write_log() 10 | { 11 | echo "$@" >&2 12 | } 13 | 14 | function panic() 15 | { 16 | write_log "$@" 17 | exit 1 18 | } 19 | 20 | ROOT="$(realpath $(dirname $(realpath $0)))" 21 | PATH="${ROOT}/../src/tools/svg2tvg/bin/Debug/net5.0/linux-x64:${ROOT}/../zig-out/bin:${PATH}" 22 | WORKDIR=/tmp/tvg-benchmark 23 | 24 | which convert tvg-text svgo svg2tvgt tvg-render > /dev/null 25 | 26 | [ -f "$1" ] || panic "file not found!" 27 | 28 | rm -rf "${WORKDIR}}" 29 | mkdir -p "${WORKDIR}" 30 | 31 | cp "$1" "${WORKDIR}/input.svg" 32 | 33 | svgo --quiet --config "${ROOT}/svgo.config.js" "${WORKDIR}/input.svg" >&2 34 | 35 | # WARNING: This invokes inkscape and is ultimatively slow 36 | # convert -background none "${WORKDIR}/input.svg" "${WORKDIR}/input.png" 37 | 38 | svg2tvgt --strict "${WORKDIR}/input.svg" --output "${WORKDIR}/output.tvgt" 39 | 40 | tvg-text "${WORKDIR}/output.tvgt" --output "${WORKDIR}/output.tvg" 41 | 42 | tvg-text "${WORKDIR}/output.tvg" --output "${WORKDIR}/output.svg" 43 | svgo --quiet --config "${ROOT}/svgo.config.js" "${WORKDIR}/output.svg" >&2 44 | 45 | tvg-render "${WORKDIR}/output.tvg" --output "${WORKDIR}/output.tga" --super-sampling 4 46 | convert "${WORKDIR}/output.tga" "${WORKDIR}/output.png" 47 | 48 | # compare -similarity-threshold 0.5 "${WORKDIR}/input.png" "${WORKDIR}/output.png" "${WORKDIR}/diff.png" 49 | 50 | SVG_SIZE=$(cat "${WORKDIR}/input.svg" | wc -c) 51 | TVG_SIZE=$(cat "${WORKDIR}/output.tvg" | wc -c) 52 | 53 | echo -e "$1\t${SVG_SIZE}\t${TVG_SIZE}" -------------------------------------------------------------------------------- /benchmark/benchmark-folder.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | DST="$1" 6 | DIR="$2" 7 | OUT="$3" 8 | LIMIT="$4" 9 | ROOT="$(realpath $(dirname $(realpath $0)))" 10 | 11 | [ ! -e "${DST}" ] || [ -f "${DST}" ] 12 | 13 | if [ ! -z "${LIMIT}" ]; then 14 | LIMIT=$((${LIMIT} + 0)) 15 | fi 16 | 17 | if [ -z "${DIR}" ]; then 18 | DIR="." 19 | fi 20 | 21 | [ -d "${DIR}" ] 22 | 23 | DIR=$(realpath "${DIR}") 24 | 25 | if [ ! -z "${OUT}" ]; then 26 | 27 | if [ ! -e "${OUT}" ]; then 28 | mkdir -p "${OUT}" 29 | fi 30 | 31 | if [ -d "${OUT}" ]; then 32 | rm -rf ${OUT}/* 33 | cp "${ROOT}/index.htm.head" "${OUT}/index.htm" 34 | fi 35 | fi 36 | 37 | echo "Searching ${DIR}" 38 | 39 | echo -e "Path\tSVG Size\tTVG Size" > "${DST}" 40 | 41 | OIFS="$IFS" 42 | IFS=$'\n' 43 | for file in $(find "${DIR}" -name "*.svg"); do 44 | 45 | echo -n "Converting ${file} ..." 46 | 47 | if "${ROOT}/bench-from-svg.sh" "$file" >> "${DST}" ; then 48 | if [ ! -z "${OUT}" ]; then 49 | RELPATH="$(realpath "--relative-to=${DIR}" "${file}")" 50 | DIRNAME="img/$(dirname "${RELPATH}")" 51 | 52 | mkdir -p "${OUT}/${DIRNAME}" 53 | 54 | cp "/tmp/tvg-benchmark/input.svg" "${OUT}/img/${RELPATH}" 55 | cp "/tmp/tvg-benchmark/output.svg" "${OUT}/img/${RELPATH%.svg}.ref.svg" 56 | cp "/tmp/tvg-benchmark/output.png" "${OUT}/img/${RELPATH%.svg}.png" 57 | 58 | SVG_SIZE="$(cat "/tmp/tvg-benchmark/input.svg" | wc -c)" 59 | TVG_SIZE="$(cat "/tmp/tvg-benchmark/output.tvg" | wc -c)" 60 | 61 | echo -n "${RELPATH}" >> "${OUT}/index.htm" # File Name 62 | echo -n "${SVG_SIZE}" >> "${OUT}/index.htm" # SVG Size 63 | echo -n "${TVG_SIZE}" >> "${OUT}/index.htm" # TVG Size 64 | echo -n "$((100 * ${TVG_SIZE} / ${SVG_SIZE}))%" >> "${OUT}/index.htm" # TVG/SVG Ratio 65 | echo -n "" >> "${OUT}/index.htm" # SVG original 66 | echo -n "" >> "${OUT}/index.htm" # TVG render 67 | echo "" >> "${OUT}/index.htm" # TVG reference svg 68 | 69 | fi 70 | echo -e "\b\b\bSUCCESS" 71 | else 72 | echo -e "\b\b\bFAILED" 73 | fi 74 | 75 | if [ ! -z "${LIMIT}" ]; then 76 | if [ $(cat "${DST}" | wc -l) -ge $((${LIMIT} + 1)) ]; then 77 | break 78 | fi 79 | fi 80 | 81 | done 82 | 83 | if [ ! -z "${OUT}" ]; then 84 | cat "${ROOT}/index.htm.foot" >> "${OUT}/index.htm" 85 | fi -------------------------------------------------------------------------------- /benchmark/index.htm.foot: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /benchmark/index.htm.head: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TVG/SVG comparison 6 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /benchmark/run-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | ROOT="$(realpath $(dirname $(realpath $0)))" 5 | 6 | "${ROOT}/benchmark-folder.sh" "${ROOT}/../website/benchmark/freesvg.csv" ~/projects/datasets/vectors/freesvg.org/ /tmp/benchmark/freesvg/ 7 | "${ROOT}/benchmark-folder.sh" "${ROOT}/../website/benchmark/zig.csv" ~/projects/datasets/vectors/zig-logo/ /tmp/benchmark/zig/ 8 | "${ROOT}/benchmark-folder.sh" "${ROOT}/../website/benchmark/w3c.csv" ~/projects/datasets/vectors/w3c/ /tmp/benchmark/w3c/ 9 | "${ROOT}/benchmark-folder.sh" "${ROOT}/../website/benchmark/papirus.csv" ~/projects/datasets/vectors/papirus/ /tmp/benchmark/papirus/ 1000 10 | "${ROOT}/benchmark-folder.sh" "${ROOT}/../website/benchmark/material-design.csv" ~/projects/datasets/vectors/material-design/ /tmp/benchmark/material-design/ 1000 -------------------------------------------------------------------------------- /benchmark/svgo.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | full: true, 3 | multipass: true, 4 | precision: 3, 5 | // order of plugins is important to correct functionality 6 | plugins: [ 7 | 'removeDoctype', 8 | 'removeXMLProcInst', 9 | 'removeComments', 10 | 'removeMetadata', 11 | 'removeEditorsNSData', 12 | 'cleanupAttrs', 13 | 'inlineStyles', 14 | 'minifyStyles', 15 | 'convertStyleToAttrs', 16 | 'cleanupIDs', 17 | 'removeRasterImages', 18 | 'removeUselessDefs', 19 | 'cleanupNumericValues', 20 | 'cleanupListOfValues', 21 | 'convertColors', 22 | 'removeUnknownsAndDefaults', 23 | 'removeNonInheritableGroupAttrs', 24 | 'removeUselessStrokeAndFill', 25 | 'cleanupEnableBackground', 26 | 'removeHiddenElems', 27 | 'removeEmptyText', 28 | 'convertShapeToPath', 29 | 'moveElemsAttrsToGroup', 30 | 'moveGroupAttrsToElems', 31 | 'collapseGroups', 32 | { 33 | name: 'convertPathData', 34 | params: { 35 | forceAbsolutePath: true, 36 | }, 37 | }, 38 | 'convertTransform', 39 | 'removeEmptyAttrs', 40 | 'removeEmptyContainers', 41 | 'mergePaths', 42 | 'removeUnusedNS', 43 | 'sortAttrs', 44 | 'removeTitle', 45 | 'removeDesc', 46 | 'removeStyleElement', 47 | 'removeScriptElement', 48 | ], 49 | js2svg: { 50 | pretty: false, 51 | indent: '' 52 | } 53 | }; -------------------------------------------------------------------------------- /benchmark/w3c-files.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikskuh/TinyVG/856986971a18ac742d25103d2de9b8b807a8bbc0/benchmark/w3c-files.pdf -------------------------------------------------------------------------------- /build-sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rm -rf sdk-release 6 | mkdir sdk-release 7 | 8 | cp documents/sdk-readme.txt sdk-release/README.txt 9 | 10 | echo "Prepare examples..." 11 | mkdir -p sdk-release/examples/{code,graphics} 12 | cp examples/native/usage.c sdk-release/examples/code/usage.c 13 | cp examples/web/index.htm sdk-release/examples/code/polyfill.htm 14 | 15 | cp design/logo.tvg sdk-release/examples/graphics/tinyvg.tvg 16 | cp examples/tinyvg/everything.tvg sdk-release/examples/graphics/feature-test.tvg 17 | cp website/img/shield.tvg sdk-release/examples/graphics/shield.tvg 18 | cp website/img/tiger.tvg sdk-release/examples/graphics/tiger.tvg 19 | cp website/img/flowchart.tvg sdk-release/examples/graphics/flowchart.tvg 20 | cp website/img/comic.tvg sdk-release/examples/graphics/comic.tvg 21 | cp website/img/chart.tvg sdk-release/examples/graphics/chart.tvg 22 | cp website/img/app-icon.tvg sdk-release/examples/graphics/app-icon.tvg 23 | 24 | echo "Prepare Zig package" 25 | mkdir -p sdk-release/zig/ 26 | cp -r vendor/parser-toolkit/src sdk-release/zig/ptk 27 | cp -r src/lib/* sdk-release/zig 28 | 29 | echo "Build native libraries" 30 | zig build -Drelease -Dlibs=false -Dheaders=true -Dtools=false --prefix sdk-release/native install 31 | zig build -Drelease -Dlibs=true -Dheaders=false -Dtools=true --prefix sdk-release/native/x86_64-windows -Dtarget=x86_64-windows install 32 | zig build -Drelease -Dlibs=true -Dheaders=false -Dtools=true --prefix sdk-release/native/x86_64-macos -Dtarget=x86_64-macos install 33 | zig build -Drelease -Dlibs=true -Dheaders=false -Dtools=true --prefix sdk-release/native/x86_64-linux -Dtarget=x86_64-linux install 34 | zig build -Drelease -Dlibs=true -Dheaders=false -Dtools=true --prefix sdk-release/native/aarch64-macos -Dtarget=x86_64-macos install 35 | zig build -Drelease -Dlibs=true -Dheaders=false -Dtools=true --prefix sdk-release/native/aarch64-linux -Dtarget=x86_64-linux install 36 | 37 | # patch the dll files 38 | mv sdk-release/native/x86_64-windows/lib/tinyvg{.dll,}.dll 39 | mv sdk-release/native/x86_64-windows/lib/tinyvg{.dll,}.pdb 40 | 41 | echo "Build wasm polyfill" 42 | zig build -Drelease -Dlibs=false -Dheaders=false -Dtools=false -Dpolyfill --prefix sdk-release/ 43 | mv sdk-release/{www,js} 44 | 45 | echo "Build specification" 46 | ./build-spec.sh sdk-release/specification.pdf 47 | 48 | echo "Build dotnet tooling" 49 | 50 | make -C src/tools/svg2tvg/ publish 51 | cp -r src/tools/svg2tvg/release/win-x64/* sdk-release/native/x86_64-windows/bin/ 52 | cp -r src/tools/svg2tvg/release/linux-x64/* sdk-release/native/x86_64-linux/bin/ 53 | cp -r src/tools/svg2tvg/release/osx-x64/* sdk-release/native/x86_64-macos/bin/ 54 | cp -r src/tools/svg2tvg/release/linux-arm64/* sdk-release/native/aarch64-linux/bin/ 55 | -------------------------------------------------------------------------------- /build-spec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | exec markdown-pdf \ 4 | --paper-format A4 \ 5 | --paper-orientation portrait \ 6 | --out "$1" \ 7 | --cwd documents \ 8 | --runnings-path documents/helper/runnings.js \ 9 | --css-path documents/helper/style.css \ 10 | documents/specification.md -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const pkgs = struct { 4 | // TinyVG package 5 | const tvg = std.build.Pkg{ 6 | .name = "tvg", 7 | .path = .{ .path = "src/lib/tinyvg.zig" }, 8 | .dependencies = &.{ptk}, 9 | }; 10 | const ptk = std.build.Pkg{ 11 | .name = "ptk", 12 | .path = .{ .path = "vendor/parser-toolkit/src/main.zig" }, 13 | }; 14 | 15 | const args = std.build.Pkg{ 16 | .name = "args", 17 | .path = .{ .path = "vendor/zig-args/args.zig" }, 18 | }; 19 | }; 20 | 21 | fn initNativeLibrary(lib: *std.build.LibExeObjStep, mode: std.builtin.Mode, target: std.zig.CrossTarget) void { 22 | lib.addPackage(pkgs.tvg); 23 | lib.addIncludeDir("src/binding/include"); 24 | lib.setBuildMode(mode); 25 | lib.setTarget(target); 26 | lib.bundle_compiler_rt = true; 27 | } 28 | 29 | pub fn build(b: *std.build.Builder) !void { 30 | const www_folder = std.build.InstallDir{ .custom = "www" }; 31 | 32 | const is_release = b.option(bool, "release", "Prepares a release build") orelse false; 33 | const enable_polyfill = b.option(bool, "polyfill", "Enables the polyfill build") orelse !is_release; 34 | const enable_poly_example = b.option(bool, "web-example", "Adds example files to the prefix/www folder for easier development") orelse (enable_polyfill and !is_release); 35 | 36 | const bundle_libs = b.option(bool, "libs", "Install the libs") orelse true; 37 | const bundle_headers = b.option(bool, "headers", "Install the headers") orelse true; 38 | const bundle_tools = b.option(bool, "tools", "Install the libs") orelse true; 39 | 40 | const target = b.standardTargetOptions(.{}); 41 | const mode = if (is_release) .ReleaseSafe else b.standardReleaseOptions(); 42 | 43 | const static_native_lib = b.addStaticLibrary("tinyvg", "src/binding/binding.zig"); 44 | initNativeLibrary(static_native_lib, mode, target); 45 | if (bundle_libs) { 46 | static_native_lib.install(); 47 | } 48 | 49 | const dynamic_native_lib = b.addSharedLibrary("tinyvg.dll", "src/binding/binding.zig", .unversioned); 50 | initNativeLibrary(dynamic_native_lib, mode, target); 51 | if (bundle_libs) { 52 | dynamic_native_lib.install(); 53 | } 54 | 55 | if (bundle_headers) { 56 | const install_header = b.addInstallFileWithDir(.{ .path = "src/binding/include/tinyvg.h" }, .header, "tinyvg.h"); 57 | b.getInstallStep().dependOn(&install_header.step); 58 | } 59 | 60 | const render = b.addExecutable("tvg-render", "src/tools/render.zig"); 61 | render.setBuildMode(mode); 62 | render.setTarget(target); 63 | render.addPackage(pkgs.tvg); 64 | render.addPackage(pkgs.args); 65 | if (bundle_tools) { 66 | render.install(); 67 | } 68 | 69 | const text = b.addExecutable("tvg-text", "src/tools/text.zig"); 70 | text.setBuildMode(mode); 71 | text.setTarget(target); 72 | text.addPackage(pkgs.tvg); 73 | text.addPackage(pkgs.args); 74 | text.addPackage(pkgs.ptk); 75 | if (bundle_tools) { 76 | text.install(); 77 | } 78 | 79 | const ground_truth_generator = b.addExecutable("ground-truth-generator", "src/data/ground-truth.zig"); 80 | ground_truth_generator.setBuildMode(mode); 81 | ground_truth_generator.addPackage(pkgs.tvg); 82 | 83 | const generate_ground_truth = ground_truth_generator.run(); 84 | generate_ground_truth.cwd = "examples/tinyvg"; 85 | 86 | const gen_gt_step = b.step("generate", "Regenerates the ground truth data."); 87 | gen_gt_step.dependOn(&generate_ground_truth.step); 88 | 89 | const files = [_][]const u8{ 90 | // "app_menu.tvg", "workspace.tvg", "workspace_add.tvg", "feature-showcase.tvg", "arc-variants.tvg", , 91 | "shield-16.tvg", "shield-8.tvg", "shield-32.tvg", 92 | "everything.tvg", "everything-32.tvg", 93 | }; 94 | inline for (files) |file| { 95 | const tvg_conversion = render.run(); 96 | tvg_conversion.addArg(file); 97 | tvg_conversion.addArg("--super-sampling"); 98 | tvg_conversion.addArg("4"); // 16 times multisampling 99 | tvg_conversion.addArg("--output"); 100 | tvg_conversion.addArg(file[0 .. file.len - 3] ++ "tga"); 101 | tvg_conversion.cwd = "examples/tinyvg"; 102 | 103 | const tvgt_conversion = text.run(); 104 | tvgt_conversion.addArg(file); 105 | tvgt_conversion.addArg("--output"); 106 | tvgt_conversion.addArg(file[0 .. file.len - 3] ++ "tvgt"); 107 | tvgt_conversion.cwd = "examples/tinyvg"; 108 | 109 | const png_conversion = b.addSystemCommand(&[_][]const u8{ 110 | "convert", 111 | "-strip", 112 | file[0 .. file.len - 3] ++ "tga", 113 | file[0 .. file.len - 3] ++ "png", 114 | }); 115 | png_conversion.cwd = "examples/tinyvg"; 116 | png_conversion.step.dependOn(&tvg_conversion.step); 117 | 118 | gen_gt_step.dependOn(&tvgt_conversion.step); 119 | gen_gt_step.dependOn(&png_conversion.step); 120 | } 121 | { 122 | const tvg_tests = b.addTestSource(pkgs.tvg.path); 123 | for (pkgs.tvg.dependencies.?) |dep| { 124 | tvg_tests.addPackage(dep); 125 | } 126 | 127 | tvg_tests.addPackage(std.build.Pkg{ 128 | .name = "ground-truth", 129 | .path = .{ .path = "src/data/ground-truth.zig" }, 130 | .dependencies = &[_]std.build.Pkg{ 131 | pkgs.tvg, 132 | }, 133 | }); 134 | 135 | const static_binding_test = b.addExecutable("static-native-binding", null); 136 | static_binding_test.setBuildMode(mode); 137 | static_binding_test.linkLibC(); 138 | static_binding_test.addIncludeDir("src/binding/include"); 139 | static_binding_test.addCSourceFile("examples/native/usage.c", &[_][]const u8{ "-Wall", "-Wextra", "-pedantic", "-std=c99" }); 140 | static_binding_test.linkLibrary(static_native_lib); 141 | 142 | const dynamic_binding_test = b.addExecutable("static-native-binding", null); 143 | dynamic_binding_test.setBuildMode(mode); 144 | dynamic_binding_test.linkLibC(); 145 | dynamic_binding_test.addIncludeDir("src/binding/include"); 146 | dynamic_binding_test.addCSourceFile("examples/native/usage.c", &[_][]const u8{ "-Wall", "-Wextra", "-pedantic", "-std=c99" }); 147 | dynamic_binding_test.linkLibrary(dynamic_native_lib); 148 | 149 | const static_binding_test_run = static_binding_test.run(); 150 | static_binding_test_run.cwd = "zig-cache"; 151 | 152 | const dynamic_binding_test_run = dynamic_binding_test.run(); 153 | dynamic_binding_test_run.cwd = "zig-cache"; 154 | 155 | const test_step = b.step("test", "Runs all tests"); 156 | test_step.dependOn(&tvg_tests.step); 157 | test_step.dependOn(&static_binding_test_run.step); 158 | if (!is_release) { 159 | // workaround for https://github.com/ziglang/zig/pull/10347/files 160 | test_step.dependOn(&dynamic_binding_test_run.step); 161 | } 162 | } 163 | { 164 | const merge_covs = b.addSystemCommand(&[_][]const u8{ 165 | "kcov", 166 | "--merge", 167 | b.pathFromRoot("kcov-output"), 168 | b.pathFromRoot("kcov-output"), 169 | }); 170 | inline for (files) |file| { 171 | merge_covs.addArg(b.pathJoin(&[_][]const u8{ b.pathFromRoot("kcov-output"), file })); 172 | } 173 | 174 | const tvg_coverage = b.addTest("src/lib/tvg.zig"); 175 | tvg_coverage.addPackage(std.build.Pkg{ 176 | .name = "ground-truth", 177 | .path = .{ .path = "src/data/ground-truth.zig" }, 178 | .dependencies = &[_]std.build.Pkg{ 179 | pkgs.tvg, 180 | }, 181 | }); 182 | tvg_coverage.setExecCmd(&[_]?[]const u8{ 183 | "kcov", 184 | "--exclude-path=~/software/zig-current", 185 | b.pathFromRoot("kcov-output"), // output dir for kcov 186 | null, // to get zig to use the --test-cmd-bin flag 187 | }); 188 | 189 | const generator_coverage = b.addSystemCommand(&[_][]const u8{ 190 | "kcov", 191 | "--exclude-path=~/software/zig-current", 192 | b.pathFromRoot("kcov-output"), // output dir for kcov 193 | }); 194 | generator_coverage.addArtifactArg(ground_truth_generator); 195 | 196 | inline for (files) |file| { 197 | const tvg_conversion = b.addSystemCommand(&[_][]const u8{ 198 | "kcov", 199 | "--exclude-path=~/software/zig-current", 200 | b.pathJoin(&[_][]const u8{ b.pathFromRoot("kcov-output"), file }), // output dir for kcov 201 | }); 202 | tvg_conversion.addArtifactArg(render); 203 | tvg_conversion.addArg(file); 204 | tvg_conversion.addArg("--output"); 205 | tvg_conversion.addArg(file[0 .. file.len - 3] ++ "tga"); 206 | tvg_conversion.cwd = "examples/tinyvg"; 207 | 208 | merge_covs.step.dependOn(&tvg_conversion.step); 209 | } 210 | 211 | merge_covs.step.dependOn(&tvg_coverage.step); 212 | merge_covs.step.dependOn(&generator_coverage.step); 213 | 214 | const coverage_step = b.step("coverage", "Generates ground truth and runs all tests with kcov"); 215 | coverage_step.dependOn(&merge_covs.step); 216 | } 217 | 218 | // web stuff 219 | if (enable_polyfill) { 220 | const polyfill = b.addSharedLibrary("tinyvg", "src/polyfill/tinyvg.zig", .unversioned); 221 | if (is_release) { 222 | polyfill.setBuildMode(.ReleaseSmall); 223 | polyfill.strip = true; 224 | } else { 225 | polyfill.setBuildMode(mode); 226 | } 227 | polyfill.setTarget(.{ 228 | .cpu_arch = .wasm32, 229 | .cpu_model = .baseline, 230 | .os_tag = .freestanding, 231 | }); 232 | polyfill.addPackage(pkgs.tvg); 233 | 234 | polyfill.install(); 235 | polyfill.install_step.?.dest_dir = www_folder; 236 | 237 | if (enable_polyfill) { 238 | const release_files = [_][]const u8{ 239 | "src/polyfill/tinyvg.js", 240 | }; 241 | const debug_files = [_][]const u8{ 242 | "examples/web/index.htm", 243 | "examples/tinyvg/shield-16.tvg", 244 | "examples/tinyvg/everything-32.tvg", 245 | "src/polyfill/tinyvg.js", 246 | }; 247 | 248 | const web_example_files = if (enable_poly_example) 249 | &debug_files 250 | else 251 | &release_files; 252 | 253 | for (web_example_files) |src_path| { 254 | const copy_stuff = b.addInstallFileWithDir(.{ .path = src_path }, www_folder, std.fs.path.basename(src_path)); 255 | if (target.isNative() and enable_poly_example) { 256 | copy_stuff.step.dependOn(gen_gt_step); 257 | } 258 | b.getInstallStep().dependOn(©_stuff.step); 259 | } 260 | } 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /design/README.md: -------------------------------------------------------------------------------- 1 | # Design Files 2 | 3 | ## Source Files 4 | 5 | - `social-media-preview.xcf`: The source of the social media preview for this github repo 6 | - `logo.svg`: the TinyVG logo file created with inkscape. Contains all the metadata 7 | 8 | ## Renders 9 | 10 | - `logo.png`: The logo rendered as a PNG file 11 | - `logo.tvg`: The logo as a binary TinyVG file 12 | - `logo.tvgt`: The logo as a textual TinyVG file 13 | - `social-media-preview.png`: The exported social media preview 14 | 15 | ## Aux 16 | 17 | - `render.sh`: Renders `logo.svg` into the other three logo files. Requires `svgo`, `convert` from ImageMagick and the repo to be built. 18 | - `svgo.config.js`: SVGO configuration 19 | -------------------------------------------------------------------------------- /design/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikskuh/TinyVG/856986971a18ac742d25103d2de9b8b807a8bbc0/design/logo.png -------------------------------------------------------------------------------- /design/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 47 | 51 | 55 | 59 | 63 | 67 | 71 | 75 | 79 | 82 | 83 | 85 | 90 | 95 | 100 | 103 | 106 | 109 | 112 | 115 | 118 | 121 | 124 | 127 | 130 | 133 | 136 | 139 | 142 | 145 | 148 | 151 | 154 | 155 | 159 | 163 | 166 | 169 | 172 | 175 | 178 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /design/logo.tvg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikskuh/TinyVG/856986971a18ac742d25103d2de9b8b807a8bbc0/design/logo.tvg -------------------------------------------------------------------------------- /design/render.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | function write_log() 6 | { 7 | echo "$@" >&2 8 | } 9 | 10 | ROOT="$(realpath $(dirname $(realpath $0)))" 11 | 12 | PATH="${ROOT}/../src/tools/svg2tvg/bin/Debug/net5.0/linux-x64:${ROOT}/../zig-out/bin:${PATH}" 13 | 14 | # Check for tool availability 15 | which convert tvg-text svgo svg2tvgt tvg-render > /dev/null 16 | 17 | write_log "Optimize SVG" 18 | svgo --config "${ROOT}/svgo.config.js" --output "${ROOT}/logo.copy.svg" --input "${ROOT}/logo.svg" >&2 19 | 20 | write_log "Convert to TVGT" 21 | svg2tvgt "${ROOT}/logo.copy.svg" --output "${ROOT}/logo.tvgt" 22 | 23 | write_log "Convert to TVG" 24 | tvg-text "${ROOT}/logo.tvgt" --output "${ROOT}/logo.tvg" 25 | 26 | write_log "Render TVG" 27 | tvg-render -g 512x512 --super-sampling 4 "${ROOT}/logo.tvg" 28 | 29 | write_log "Convert to PNG" 30 | convert "${ROOT}/logo.tga" "${ROOT}/logo.png" 31 | 32 | write_log "Print statistics" 33 | 34 | echo "Source SVG: $(( $(wc -c < "${ROOT}/logo.svg") ))" 35 | echo "Optimized SVG: $(( $(wc -c < "${ROOT}/logo.copy.svg") ))" 36 | echo "Final TVG: $(( $(wc -c < "${ROOT}/logo.tvg") ))" 37 | echo "Compression: $(( 100 * $(wc -c < "${ROOT}/logo.tvg") / $(wc -c < "${ROOT}/logo.copy.svg") ))%" 38 | 39 | write_log "Delete intermediate file" 40 | rm "${ROOT}/logo.tga" 41 | rm "${ROOT}/logo.copy.svg" 42 | -------------------------------------------------------------------------------- /design/social-media-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikskuh/TinyVG/856986971a18ac742d25103d2de9b8b807a8bbc0/design/social-media-preview.png -------------------------------------------------------------------------------- /design/social-media-preview.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikskuh/TinyVG/856986971a18ac742d25103d2de9b8b807a8bbc0/design/social-media-preview.xcf -------------------------------------------------------------------------------- /design/svgo.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | full: true, 3 | multipass: true, 4 | precision: 3, 5 | // order of plugins is important to correct functionality 6 | plugins: [ 7 | 'removeDoctype', 8 | 'removeXMLProcInst', 9 | 'removeComments', 10 | 'removeMetadata', 11 | 'removeEditorsNSData', 12 | 'cleanupAttrs', 13 | 'inlineStyles', 14 | 'minifyStyles', 15 | 'convertStyleToAttrs', 16 | 'cleanupIDs', 17 | 'removeRasterImages', 18 | 'removeUselessDefs', 19 | 'cleanupNumericValues', 20 | 'cleanupListOfValues', 21 | 'convertColors', 22 | 'removeUnknownsAndDefaults', 23 | 'removeNonInheritableGroupAttrs', 24 | 'removeUselessStrokeAndFill', 25 | 'cleanupEnableBackground', 26 | 'removeHiddenElems', 27 | 'removeEmptyText', 28 | 'convertShapeToPath', 29 | 'moveElemsAttrsToGroup', 30 | 'moveGroupAttrsToElems', 31 | 'collapseGroups', 32 | { 33 | name: 'convertPathData', 34 | params: { 35 | forceAbsolutePath: true, 36 | }, 37 | }, 38 | 'convertTransform', 39 | 'removeEmptyAttrs', 40 | 'removeEmptyContainers', 41 | 'mergePaths', 42 | 'removeUnusedNS', 43 | 'sortAttrs', 44 | 'removeTitle', 45 | 'removeDesc', 46 | 'removeStyleElement', 47 | 'removeScriptElement', 48 | ], 49 | js2svg: { 50 | pretty: false, 51 | indent: '' 52 | } 53 | }; -------------------------------------------------------------------------------- /documents/.gitignore: -------------------------------------------------------------------------------- 1 | specification.pdf 2 | -------------------------------------------------------------------------------- /documents/graphics/gradients.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /documents/graphics/gradients.tvgt: -------------------------------------------------------------------------------- 1 | (tvg 1 2 | (160 60 1/1 u8888 default) 3 | ( 4 | (1 0 0) 5 | (0 0 0) 6 | (1 1 1) 7 | ) 8 | ( 9 | (outline_fill_rectangles (flat 1) (flat 0) 2.0 10 | ( 11 | (10 10 40 40) 12 | ) 13 | ) 14 | (outline_fill_rectangles (linear (70 25) (90 25) 1 2) (flat 0) 2.0 15 | ( 16 | (60 10 40 40) 17 | ) 18 | ) 19 | (outline_fill_rectangles (radial (120 30) (150 30) 1 2) (flat 0) 2.0 20 | ( 21 | (110 10 40 40) 22 | ) 23 | ) 24 | ) 25 | ) -------------------------------------------------------------------------------- /documents/graphics/outline-polgon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /documents/graphics/outline-polygon.tvgt: -------------------------------------------------------------------------------- 1 | (tvg 1 2 | (50 50 1/1 u8888 default) 3 | ( 4 | (0 0 0) 5 | (0.8 0.8 0.8) 6 | ) 7 | ( 8 | (outline_fill_polygon (flat 1) (flat 0) 2.0 9 | ( 10 | (10 10) 11 | (20 10) 12 | (20 20) 13 | (30 20) 14 | (30 10) 15 | (40 10) 16 | (40 40) 17 | (10 40) 18 | ) 19 | ) 20 | ) 21 | ) -------------------------------------------------------------------------------- /documents/graphics/outline-rectangles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /documents/graphics/outline-rectangles.tvgt: -------------------------------------------------------------------------------- 1 | (tvg 1 2 | (140 90 1/1 u8888 default) 3 | ( 4 | (0 0 0) 5 | (0.8 0.8 0.8) 6 | ) 7 | ( 8 | (outline_fill_rectangles (flat 1) (flat 0) 2.0 9 | ( 10 | (10 10 100 50) 11 | (20 20 100 50) 12 | (30 30 100 50) 13 | ) 14 | ) 15 | ) 16 | ) -------------------------------------------------------------------------------- /documents/graphics/overview.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | CommandCommandEnd Of FileCommandCommandColor TableHeader 90 | -------------------------------------------------------------------------------- /documents/graphics/overview.uxf: -------------------------------------------------------------------------------- 1 | 10UMLClass22016020040valign=center 2 | lw=1 3 | HeaderUMLClass22020020060valign=center 4 | lw=1 5 | Color TableUMLClass22026020020valign=center 6 | lw=1 7 | CommandUMLClass22028020040valign=center 8 | lw=1 9 | CommandUMLClass22038020030valign=center 10 | lw=1 11 | End Of FileUMLClass22035020030valign=center 12 | lw=1 13 | CommandUMLClass220160200250lw=6 14 | bg=white 15 | transparency=0 16 | layer=-1UMLClass22032020030valign=center 17 | lw=1 18 | Command -------------------------------------------------------------------------------- /documents/helper/runnings.js: -------------------------------------------------------------------------------- 1 | exports.header = { 2 | height: "2cm", 3 | contents: function(pageNum, numPages) { 4 | if(pageNum > 1) { 5 | return '
' + 6 | // '' + 7 | 'TinyVG Specification' + pageNum + ' / ' + numPages + '' + 8 | '
'; 9 | }else { 10 | return ""; 11 | } 12 | } 13 | } 14 | 15 | exports.footer = null 16 | 17 | hello -------------------------------------------------------------------------------- /documents/helper/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 8pt; 3 | } 4 | 5 | table { 6 | border: 2px solid black; 7 | border-collapse: collapse; 8 | width: 100%; 9 | } 10 | 11 | table tr { 12 | border: 1px solid silver; 13 | } 14 | 15 | table tr td, 16 | table tr th { 17 | border-left: 1px solid gray; 18 | border-right: 1px solid gray; 19 | vertical-align: top; 20 | } 21 | 22 | table th { 23 | text-align: left; 24 | } 25 | 26 | img, 27 | svg { 28 | max-height: 10rem; 29 | margin-left: auto; 30 | margin-right: auto; 31 | } 32 | 33 | a { 34 | color: navy; 35 | text-decoration: none; 36 | } 37 | 38 | div, 39 | img, 40 | table { 41 | break-inside: avoid; 42 | page-break-inside: avoid; 43 | } 44 | h1, 45 | h2, 46 | h3, 47 | h4, 48 | h5, 49 | h6 { 50 | break-inside: avoid; 51 | page-break-after: avoid; 52 | } 53 | 54 | h2 { 55 | border-bottom: 1px solid #000000; 56 | } 57 | 58 | h3 { 59 | border-bottom: 1px solid #cccccc; 60 | } 61 | 62 | h4 { 63 | border-bottom: 1px solid #888888; 64 | } 65 | -------------------------------------------------------------------------------- /documents/sdk-readme.txt: -------------------------------------------------------------------------------- 1 | 2 | ███████ █ █ ▗█████▖ ▗█████▖ ██████▖ █ ▗█▘ 3 | █ █ █▖ █ █▖ ▗█ █ █ █▘ █ █▘ ▝█ █ ▝█ █ ▗█▘ 4 | █ █ ██▖ █ ▝█▄█▘ █ █ █ █▖ █ █ █ ▗█▘ 5 | █ █ █▝█▖ █ ▝█▘ █▖ ▗█ █ ████ ▝█████▖ █ █ ███▌ 6 | █ █ █ ▝█▖█ █ ▝█▖ ▗█▘ █ █ ▝█ █ █ █ ▝█▖ 7 | █ █ █ ▝██ █ ▝█▄█▘ █▖ ▗█ █▖ ▗█ █ ▗█ █ ▝█▖ 8 | █ █ █ ▝█ █ ▝█▘ ▝█████▘ ▝█████▘ ██████▘ █ ▝█▖ 9 | 10 | Introduction: 11 | This is the SDK for the TinyVG vector graphics format. 12 | 13 | Structure: 14 | ├── examples => Contains both image and code examples 15 | ├── js => Contains the polyfill to use TinyVG on websites 16 | ├── native => Contains tooling and libraries for native development 17 | ├── specification.pdf => The format specification 18 | └── zig => Contains a zig package. 19 | 20 | Known problems: 21 | - x86_64-windows static library does not work with VisualStudio 22 | - macos dynamic library requires rpath patching 23 | - aarch64-macos doesn't have svg2tvgt 24 | - dynamic linking of static library doesn't work on void-musl 25 | -------------------------------------------------------------------------------- /documents/text-format.md: -------------------------------------------------------------------------------- 1 | # TVG Text Format 2 | 3 | This document is an auxiliary document side-by-side to the TVG specification to allow a non-binary represenation of TVG files. 4 | 5 | This format is meant for debugging/development and is not required to be implemented by conforming implementations. 6 | 7 | ## Structure 8 | 9 | ````lisp 10 | (tvg 1 11 | ( ) 12 | ( 13 | (r g b) 14 | (r g b) 15 | (r g b a) 16 | ... 17 | ) 18 | ( 19 | ( 20 | fill_rectangles 21 |
File PathSVG SizeTVG SizeTVG/SVG RatioSVG OriginalTVG RenderingTVG Data