├── .Rbuildignore ├── .github ├── .gitignore ├── CODE_OF_CONDUCT.md └── workflows │ ├── R-CMD-check.yaml │ ├── pkgdown.yaml │ ├── pr-commands.yaml │ └── test-coverage.yaml ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── DESCRIPTION ├── NAMESPACE ├── NEWS.md ├── R ├── SVG.R ├── aaa.R ├── cpp11.R ├── fonts.R ├── import-standalone-obj-type.R ├── import-standalone-types-check.R ├── inlineSVG.R ├── svglite-package.R └── utils.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── air.toml ├── codecov.yml ├── cran-comments.md ├── man ├── add_web_fonts.Rd ├── create_svgz.Rd ├── editSVG.Rd ├── figures │ ├── README-unnamed-chunk-3-1.png │ ├── lifecycle-archived.svg │ ├── lifecycle-defunct.svg │ ├── lifecycle-deprecated.svg │ ├── lifecycle-experimental.svg │ ├── lifecycle-maturing.svg │ ├── lifecycle-questioning.svg │ ├── lifecycle-stable.svg │ ├── lifecycle-superseded.svg │ ├── logo.png │ └── logo.svg ├── font_face.Rd ├── htmlSVG.Rd ├── reexports.Rd ├── stringSVG.Rd ├── svglite-package.Rd ├── svglite.Rd ├── svgstring.Rd └── xmlSVG.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── revdep ├── .gitignore ├── README.md ├── cran.md ├── failures.md └── problems.md ├── src ├── .gitignore ├── Makevars ├── Makevars.ucrt ├── Makevars.win ├── SvgStream.cpp ├── SvgStream.h ├── cpp11.cpp ├── devSVG.cpp ├── svglite_types.h ├── tinyformat.h └── utils.h ├── svglite.Rproj ├── tests ├── testthat.R └── testthat │ ├── _snaps │ ├── ids.md │ └── text-fonts.md │ ├── helper-aliases.R │ ├── helper-manual.R │ ├── helper-style.R │ ├── test-clip.R │ ├── test-clip.svg │ ├── test-colour.R │ ├── test-devSVG.R │ ├── test-ids.R │ ├── test-lines.R │ ├── test-no-clip.svg │ ├── test-output.R │ ├── test-path.R │ ├── test-points.R │ ├── test-raster.R │ ├── test-rect.R │ ├── test-scale-text.html │ ├── test-scale-text.svg │ ├── test-scale.R │ ├── test-text-fonts.R │ ├── test-text.R │ └── test-text.svg ├── tools └── winlibs.R └── vignettes ├── fonts.Rmd └── scaling.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | ^Rplots\.svg$ 5 | ^README\.Rmd$ 6 | ^README-.*\.png$ 7 | ^cran-comments\.md$ 8 | ^revdep/$ 9 | ^revdep$ 10 | ^codecov\.yml$ 11 | ^docs/$ 12 | ^docs$ 13 | ^CRAN-RELEASE$ 14 | ^\.github$ 15 | ^_pkgdown\.yml$ 16 | ^pkgdown$ 17 | ^CODE_OF_CONDUCT\.md$ 18 | ^CRAN-SUBMISSION$ 19 | ^compile_commands\.json$ 20 | ^\.cache$ 21 | ^[\.]?air\.toml$ 22 | ^\.vscode$ 23 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual 10 | identity and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or advances of 31 | any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email address, 35 | without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at codeofconduct@posit.co. 63 | All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series of 85 | actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or permanent 92 | ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within the 112 | community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.1, available at 118 | . 119 | 120 | Community Impact Guidelines were inspired by 121 | [Mozilla's code of conduct enforcement ladder][https://github.com/mozilla/inclusion]. 122 | 123 | For answers to common questions about this code of conduct, see the FAQ at 124 | . Translations are available at . 125 | 126 | [homepage]: https://www.contributor-covenant.org 127 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | # 4 | # NOTE: This workflow is overkill for most R packages and 5 | # check-standard.yaml is likely a better choice. 6 | # usethis::use_github_action("check-standard") will install it. 7 | on: 8 | push: 9 | branches: [main, master] 10 | pull_request: 11 | 12 | name: R-CMD-check.yaml 13 | 14 | permissions: read-all 15 | 16 | jobs: 17 | R-CMD-check: 18 | runs-on: ${{ matrix.config.os }} 19 | 20 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | config: 26 | - {os: macos-latest, r: 'release'} 27 | 28 | - {os: windows-latest, r: 'release'} 29 | # use 4.0 or 4.1 to check with rtools40's older compiler 30 | - {os: windows-latest, r: 'oldrel-4'} 31 | 32 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 33 | - {os: ubuntu-latest, r: 'release'} 34 | - {os: ubuntu-latest, r: 'oldrel-1'} 35 | - {os: ubuntu-latest, r: 'oldrel-2'} 36 | - {os: ubuntu-latest, r: 'oldrel-3'} 37 | - {os: ubuntu-latest, r: 'oldrel-4'} 38 | 39 | env: 40 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 41 | R_KEEP_PKG_SOURCE: yes 42 | 43 | steps: 44 | - uses: actions/checkout@v4 45 | 46 | - uses: r-lib/actions/setup-pandoc@v2 47 | 48 | - uses: r-lib/actions/setup-r@v2 49 | with: 50 | r-version: ${{ matrix.config.r }} 51 | http-user-agent: ${{ matrix.config.http-user-agent }} 52 | use-public-rspm: true 53 | 54 | - uses: r-hub/actions/setup-r-sysreqs@v1 55 | with: 56 | type: minimal 57 | 58 | - uses: r-lib/actions/setup-r-dependencies@v2 59 | with: 60 | extra-packages: any::rcmdcheck 61 | needs: check 62 | 63 | - uses: r-lib/actions/check-r-package@v2 64 | with: 65 | upload-snapshots: true 66 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 67 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | release: 8 | types: [published] 9 | workflow_dispatch: 10 | 11 | name: pkgdown.yaml 12 | 13 | permissions: read-all 14 | 15 | jobs: 16 | pkgdown: 17 | runs-on: ubuntu-latest 18 | # Only restrict concurrency for non-PR jobs 19 | concurrency: 20 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 21 | env: 22 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 23 | permissions: 24 | contents: write 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - uses: r-lib/actions/setup-pandoc@v2 29 | 30 | - uses: r-lib/actions/setup-r@v2 31 | with: 32 | use-public-rspm: true 33 | 34 | - uses: r-lib/actions/setup-r-dependencies@v2 35 | with: 36 | extra-packages: any::pkgdown, local::. 37 | needs: website 38 | 39 | - name: Build site 40 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 41 | shell: Rscript {0} 42 | 43 | - name: Deploy to GitHub pages 🚀 44 | if: github.event_name != 'pull_request' 45 | uses: JamesIves/github-pages-deploy-action@v4.5.0 46 | with: 47 | clean: false 48 | branch: gh-pages 49 | folder: docs 50 | -------------------------------------------------------------------------------- /.github/workflows/pr-commands.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | name: pr-commands.yaml 8 | 9 | permissions: read-all 10 | 11 | jobs: 12 | document: 13 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }} 14 | name: document 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | permissions: 19 | contents: write 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - uses: r-lib/actions/pr-fetch@v2 24 | with: 25 | repo-token: ${{ secrets.GITHUB_TOKEN }} 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::roxygen2 34 | needs: pr-document 35 | 36 | - name: Document 37 | run: roxygen2::roxygenise() 38 | shell: Rscript {0} 39 | 40 | - name: commit 41 | run: | 42 | git config --local user.name "$GITHUB_ACTOR" 43 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 44 | git add man/\* NAMESPACE 45 | git commit -m 'Document' 46 | 47 | - uses: r-lib/actions/pr-push@v2 48 | with: 49 | repo-token: ${{ secrets.GITHUB_TOKEN }} 50 | 51 | style: 52 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }} 53 | name: style 54 | runs-on: ubuntu-latest 55 | env: 56 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 57 | permissions: 58 | contents: write 59 | steps: 60 | - uses: actions/checkout@v4 61 | 62 | - uses: r-lib/actions/pr-fetch@v2 63 | with: 64 | repo-token: ${{ secrets.GITHUB_TOKEN }} 65 | 66 | - uses: r-lib/actions/setup-r@v2 67 | 68 | - name: Install dependencies 69 | run: install.packages("styler") 70 | shell: Rscript {0} 71 | 72 | - name: Style 73 | run: styler::style_pkg() 74 | shell: Rscript {0} 75 | 76 | - name: commit 77 | run: | 78 | git config --local user.name "$GITHUB_ACTOR" 79 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 80 | git add \*.R 81 | git commit -m 'Style' 82 | 83 | - uses: r-lib/actions/pr-push@v2 84 | with: 85 | repo-token: ${{ secrets.GITHUB_TOKEN }} 86 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | 8 | name: test-coverage.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | test-coverage: 14 | runs-on: ubuntu-latest 15 | env: 16 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: r-lib/actions/setup-r@v2 22 | with: 23 | use-public-rspm: true 24 | 25 | - uses: r-lib/actions/setup-r-dependencies@v2 26 | with: 27 | extra-packages: any::covr, any::xml2 28 | needs: coverage 29 | 30 | - name: Test coverage 31 | run: | 32 | cov <- covr::package_coverage( 33 | quiet = FALSE, 34 | clean = FALSE, 35 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") 36 | ) 37 | print(cov) 38 | covr::to_cobertura(cov) 39 | shell: Rscript {0} 40 | 41 | - uses: codecov/codecov-action@v5 42 | with: 43 | # Fail if error if not on PR, or if on PR and token is given 44 | fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} 45 | files: ./cobertura.xml 46 | plugins: noop 47 | disable_search: true 48 | token: ${{ secrets.CODECOV_TOKEN }} 49 | 50 | - name: Show testthat output 51 | if: always() 52 | run: | 53 | ## -------------------------------------------------------------------- 54 | find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true 55 | shell: bash 56 | 57 | - name: Upload test results 58 | if: failure() 59 | uses: actions/upload-artifact@v4 60 | with: 61 | name: coverage-test-failures 62 | path: ${{ runner.temp }}/package 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | Rplots.svg 5 | inst/doc 6 | docs 7 | compile_commands.json 8 | .cache 9 | 10 | /.quarto/ 11 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Posit.air-vscode" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[r]": { 3 | "editor.formatOnSave": true, 4 | "editor.defaultFormatter": "Posit.air-vscode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: svglite 2 | Title: An 'SVG' Graphics Device 3 | Version: 2.2.1.9000 4 | Authors@R: c( 5 | person("Hadley", "Wickham", , "hadley@posit.co", role = "aut"), 6 | person("Lionel", "Henry", , "lionel@posit.co", role = "aut"), 7 | person("Thomas Lin", "Pedersen", , "thomas.pedersen@posit.co", role = c("cre", "aut"), 8 | comment = c(ORCID = "0000-0002-5147-4711")), 9 | person("T Jake", "Luciani", , "jake@apache.org", role = "aut"), 10 | person("Matthieu", "Decorde", , "matthieu.decorde@ens-lyon.fr", role = "aut"), 11 | person("Vaudor", "Lise", , "lise.vaudor@ens-lyon.fr", role = "aut"), 12 | person("Tony", "Plate", role = "ctb", 13 | comment = "Early line dashing code"), 14 | person("David", "Gohel", role = "ctb", 15 | comment = "Line dashing code and early raster code"), 16 | person("Yixuan", "Qiu", role = "ctb", 17 | comment = "Improved styles; polypath implementation"), 18 | person("Håkon", "Malmedal", role = "ctb", 19 | comment = "Opacity code"), 20 | person("Posit Software, PBC", role = c("cph", "fnd"), 21 | comment = c(ROR = "03wc8by49")) 22 | ) 23 | Description: A graphics device for R that produces 'Scalable Vector 24 | Graphics'. 'svglite' is a fork of the older 'RSvgDevice' package. 25 | License: GPL (>= 2) 26 | URL: https://svglite.r-lib.org, https://github.com/r-lib/svglite 27 | BugReports: https://github.com/r-lib/svglite/issues 28 | Depends: 29 | R (>= 4.1) 30 | Imports: 31 | base64enc, 32 | cli, 33 | lifecycle, 34 | rlang (>= 1.1.0), 35 | systemfonts (>= 1.2.3), 36 | textshaping (>= 0.3.0) 37 | Suggests: 38 | covr, 39 | fontquiver (>= 0.2.0), 40 | htmltools, 41 | knitr, 42 | rmarkdown, 43 | testthat (>= 3.0.0), 44 | xml2 (>= 1.0.0) 45 | LinkingTo: 46 | cpp11, 47 | systemfonts, 48 | textshaping 49 | VignetteBuilder: 50 | knitr 51 | Config/build/compilation-database: true 52 | Config/Needs/website: tidyverse/tidytemplate 53 | Config/testthat/edition: 3 54 | Config/usethis/last-upkeep: 2025-04-25 55 | Encoding: UTF-8 56 | Roxygen: list(markdown = TRUE) 57 | RoxygenNote: 7.3.2 58 | SystemRequirements: libpng 59 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(print,font_face) 4 | S3method(print,svg) 5 | export(add_fonts) 6 | export(add_web_fonts) 7 | export(create_svgz) 8 | export(editSVG) 9 | export(font_face) 10 | export(font_feature) 11 | export(fonts_as_import) 12 | export(htmlSVG) 13 | export(register_font) 14 | export(register_variant) 15 | export(require_font) 16 | export(stringSVG) 17 | export(svglite) 18 | export(svgstring) 19 | export(xmlSVG) 20 | import(rlang) 21 | importFrom(lifecycle,deprecated) 22 | importFrom(systemfonts,add_fonts) 23 | importFrom(systemfonts,font_feature) 24 | importFrom(systemfonts,font_info) 25 | importFrom(systemfonts,fonts_as_import) 26 | importFrom(systemfonts,match_font) 27 | importFrom(systemfonts,register_font) 28 | importFrom(systemfonts,register_variant) 29 | importFrom(systemfonts,require_font) 30 | importFrom(textshaping,text_width) 31 | useDynLib(svglite, .registration = TRUE) 32 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # svglite (development version) 2 | 3 | # svglite 2.2.1 4 | 5 | * Fix a compilation issue on Fedora 6 | 7 | # svglite 2.2.0 8 | 9 | * Added support for luminance masking (#174) 10 | * Fixed a bug in calculating text widths when using font features (#175) 11 | * Added support for path stroking and filling (#174) 12 | * Added support for groups along with affine transformation and color blending. 13 | No support for Porter-Duff composition as it is porly supported in SVG (#174) 14 | * Added better support for specifying webfonts as embedded in the SVG (#182) 15 | * Added support for glyphs by rendering them as paths or rasters. This means the 16 | text is not editable in post-production but it is better than nothing. 17 | 18 | # svglite 2.1.3 19 | 20 | * Fix a stack imbalance bug 21 | 22 | # svglite 2.1.2 23 | 24 | * Windows: use libpng included with Rtools on R 4.2 and up. 25 | * Add support for `dev.capabilities()` 26 | 27 | # svglite 2.1.1 28 | 29 | * Fix `` include at request of CRAN 30 | 31 | # svglite 2.1.0 32 | 33 | * Add new graphics engine features: 34 | - Path clipping 35 | - Masking 36 | - Pattern and gradient fills 37 | 38 | * Font family names are now quoted (#136) 39 | 40 | * svglite now renders leading white-space in nodes. (#131, @hrbrmstr) 41 | 42 | # svglite 2.0.0 43 | 44 | * svglite now uses systemfonts for text metric calculations and font family 45 | lookup. 46 | 47 | * svglite can now encode OpenType font features into the CSS if the used font 48 | contains registered features 49 | 50 | * svglite now directly encodes raster data into png instead of rendering it 51 | through cairo. If the provided raster is smaller than the final requested size 52 | it will be resized. 53 | 54 | * SVG's can now get a top-level id so that style definitions doesn't spill into 55 | the surrounding HTML (#91) 56 | 57 | * Dimensions are now encoded into the top-level `` tag (#90) 58 | 59 | * Starting a new page creates a new file if the filename supports it (#98, @vandenman). 60 | 61 | * The _inline_ devices now defaults to the same dimensions as `svglite()` (#89) 62 | 63 | * Clip defs are now only written if they don't already exist (#110) 64 | 65 | * Clipping is now defined with outer groups instead of on each element (#109) 66 | 67 | * svglite now uses cpp11 instead of Rcpp (#100) 68 | 69 | * svgz output is now supported natively (#6) 70 | 71 | * Text adjustments are now encoded in css where possible (#107) 72 | 73 | * The use of textLength CSS property can now be turned off (#118) 74 | 75 | * web font imports can now be given when creating an svg (#108) 76 | 77 | * Add scaling argument to devices to control line-width and text scaling (#115) 78 | 79 | * svg files that are being written are now only valid at all times if `always_valid` 80 | is set to `TRUE` in the `svglite()` call. 81 | 82 | * svglite now guards against attempts at writing to the device before a new page 83 | has been requested (#126) 84 | 85 | 86 | # svglite 1.2.3 87 | 88 | * The radius of circles is no longer expressed in pt (#93, @vandenman). 89 | 90 | * Dimensions smaller than 1 now retain two significant figures (#94, @ilia-kats). 91 | 92 | * @thomasp85 takes over as maintainer 93 | 94 | 95 | # svglite 1.2.2 96 | 97 | * Improvements to reproducibility of generated SVGs: Negative zeros 98 | are now treated as positive, and the clip ID are now generated from 99 | truncated elements. 100 | 101 | * svglite now uses the `polygon` SVG element. This ensures that 102 | polygons are properly closed (#82). 103 | 104 | * Text metrics are now correctly computed for Unicode characters in 105 | plotmath expressions (#81). 106 | 107 | 108 | # svglite 1.2.1 109 | 110 | This release makes svglite compatible with gdtools 0.1.6 111 | 112 | 113 | # svglite 1.2.0 114 | 115 | ## New features 116 | 117 | * The device functions gain `system_fonts` and `user_fonts` 118 | arguments. 119 | 120 | * Two new vignettes: `vignette("fonts")` and `vignette("scaling")`. 121 | The vignette on fonts explains in detail how to use the new fonts 122 | arguments and why. The vignette on scaling goes over scaling issues, 123 | e.g. when embedding svglite outputs in a web page. 124 | 125 | * `xmlSVG()` gains `height` and `width` arguments (#66). 126 | 127 | * New `stringSVG()` device function for quick testing. 128 | 129 | 130 | ## Improvements 131 | 132 | * Greatly improves the performance of `svgstring()` (#58). 133 | 134 | * Clip paths now get a unique identifier to avoid collisions when 135 | multiple plots are included in a document (#67). 136 | 137 | * Raster graphics are now correctly cropped (#64) and handle 138 | transparency properly. 139 | 140 | * The dimensions of text fields are now hardcoded in the SVGs to 141 | prevent alignment issues. 142 | 143 | 144 | ## Bug fixes 145 | 146 | * `editSVG()` works again (#56). 147 | 148 | * The dashes in lines with `lwd < 1` are scaled better (#68). 149 | 150 | * Transparent blacks are written correctly (#62, #63). 151 | 152 | * Text is now scaled correctly (#72, #59). See also the new vignette 153 | on scaling. 154 | 155 | 156 | # svglite 1.1.0 157 | 158 | * Text metrics now converted from points to pixels (#45, #48) - this 159 | fixes text alignment issues. 160 | 161 | * Intermediate outputs are always valid SVG (#53). 162 | 163 | * New `svgstring()` returns plot as a string (#40, @yixuan). 164 | 165 | * Use raster test compatible with older versions of R. 166 | 167 | * Add support for `clip()`. This also fixes a number of minor issues with 168 | grid graphics (@yixuan, #47 and #49). 169 | 170 | * Fix incorrect device size (#50). 171 | 172 | # svglite 1.0.0 173 | 174 | svglite is fully featured svg graphics device that works on all platforms, forked from RSvgDevice. It supports all graphics device features: 175 | 176 | * All types of line dashing are supported (#15). All line end and line join 177 | styles are supported (#24). 178 | 179 | * Text is now coloured, and uses the same default fonts as R (Arial, 180 | Times New Roman, and Courier). Font metrics are computed using the 181 | gdtools package so that `plotmath()` and `strwidth()` now work. 182 | 183 | * Transparent colours are now generated with `rgba()` rather than using 184 | `stroke-opacity` and `fill-opacity` styles (#16). NA fills and colours are 185 | translated to "none". 186 | 187 | * `par(bg)` affects the background colour (#8). 188 | 189 | * Rasters are supported by embedding base64-encoded pngs in a data url (#2). 190 | 191 | * `polypath()` is now supported, which also allows the `showtext` package to 192 | render fonts correctly with this device (#36). 193 | 194 | We also made a few other tweaks to the rendered SVG: 195 | 196 | * Only the `viewBox` attribute of `` is set (not `width` and `height`): 197 | I'm reasonably certain this makes it easier to use in more places (#12). 198 | 199 | * Default styling properties are specified in a global `