Git Product home page Git Product logo

svg2pdf's Introduction

Typst

Documentation Typst App Discord Server Apache-2 License Jobs at Typst

Typst is a new markup-based typesetting system that is designed to be as powerful as LaTeX while being much easier to learn and use. Typst has:

  • Built-in markup for the most common formatting tasks
  • Flexible functions for everything else
  • A tightly integrated scripting system
  • Math typesetting, bibliography management, and more
  • Fast compile times thanks to incremental compilation
  • Friendly error messages in case something goes wrong

This repository contains the Typst compiler and its CLI, which is everything you need to compile Typst documents locally. For the best writing experience, consider signing up to our collaborative online editor for free.

Example

A gentle introduction to Typst is available in our documentation. However, if you want to see the power of Typst encapsulated in one image, here it is:

Example

Let's dissect what's going on:

  • We use set rules to configure element properties like the size of pages or the numbering of headings. By setting the page height to auto, it scales to fit the content. Set rules accommodate the most common configurations. If you need full control, you can also use show rules to completely redefine the appearance of an element.

  • We insert a heading with the = Heading syntax. One equals sign creates a top level heading, two create a subheading and so on. Typst has more lightweight markup like this, see the syntax reference for a full list.

  • Mathematical equations are enclosed in dollar signs. By adding extra spaces around the contents of an equation, we can put it into a separate block. Multi-letter identifiers are interpreted as Typst definitions and functions unless put into quotes. This way, we don't need backslashes for things like floor and sqrt. And phi.alt applies the alt modifier to the phi to select a particular symbol variant.

  • Now, we get to some scripting. To input code into a Typst document, we can write a hash followed by an expression. We define two variables and a recursive function to compute the n-th fibonacci number. Then, we display the results in a center-aligned table. The table function takes its cells row-by-row. Therefore, we first pass the formulas $F_1$ to $F_8$ and then the computed fibonacci numbers. We apply the spreading operator (..) to both because they are arrays and we want to pass the arrays' items as individual arguments.

Text version of the code example.
#set page(width: 10cm, height: auto)
#set heading(numbering: "1.")

= Fibonacci sequence
The Fibonacci sequence is defined through the
recurrence relation $F_n = F_(n-1) + F_(n-2)$.
It can also be expressed in _closed form:_

$ F_n = round(1 / sqrt(5) phi.alt^n), quad
  phi.alt = (1 + sqrt(5)) / 2 $

#let count = 8
#let nums = range(1, count + 1)
#let fib(n) = (
  if n <= 2 { 1 }
  else { fib(n - 1) + fib(n - 2) }
)

The first #count numbers of the sequence are:

#align(center, table(
  columns: count,
  ..nums.map(n => $F_#n$),
  ..nums.map(n => str(fib(n))),
))

Installation

Typst's CLI is available from different sources:

  • You can get sources and pre-built binaries for the latest release of Typst from the releases page. Download the archive for your platform and place it in a directory that is in your PATH. To stay up to date with future releases, you can simply run typst update.

  • You can install Typst through different package managers. Note that the versions in the package managers might lag behind the latest release.

    • Linux: View Typst on Repology
    • macOS: brew install typst
    • Windows: winget install --id Typst.Typst
  • If you have a Rust toolchain installed, you can install

    • the latest released Typst version with cargo install --locked typst-cli
    • a development version with cargo install --git https://github.com/typst/typst --locked typst-cli
  • Nix users can

    • use the typst package with nix-shell -p typst
    • build and run a development version with nix run github:typst/typst -- --version.
  • Docker users can run a prebuilt image with docker run -it ghcr.io/typst/typst:latest.

Usage

Once you have installed Typst, you can use it like this:

# Creates `file.pdf` in working directory.
typst compile file.typ

# Creates PDF file at the desired path.
typst compile path/to/source.typ path/to/output.pdf

You can also watch source files and automatically recompile on changes. This is faster than compiling from scratch each time because Typst has incremental compilation.

# Watches source files and recompiles on changes.
typst watch file.typ

Typst further allows you to add custom font paths for your project and list all of the fonts it discovered:

# Adds additional directories to search for fonts.
typst compile --font-path path/to/fonts file.typ

# Lists all of the discovered fonts in the system and the given directory.
typst fonts --font-path path/to/fonts

# Or via environment variable (Linux syntax).
TYPST_FONT_PATHS=path/to/fonts typst fonts

For other CLI subcommands and options, see below:

# Prints available subcommands and options.
typst help

# Prints detailed usage of a subcommand.
typst help watch

If you prefer an integrated IDE-like experience with autocompletion and instant preview, you can also check out Typst's free web app.

Community

The main place where the community gathers is our Discord server. Feel free to join there to ask questions, help out others, share cool things you created with Typst, or just to chat.

Aside from that there are a few places where you can find things built by the community:

If you had a bad experience in our community, please reach out to us.

Contributing

We would love to see contributions from the community. If you experience bugs, feel free to open an issue. If you would like to implement a new feature or bug fix, please follow the steps outlined in the contribution guide.

To build Typst yourself, first ensure that you have the latest stable Rust installed. Then, clone this repository and build the CLI with the following commands:

git clone https://github.com/typst/typst
cd typst
cargo build --release

The optimized binary will be stored in target/release/.

Another good way to contribute is by sharing packages with the community.

Pronunciation and Spelling

IPA: /taɪpst/. "Ty" like in Typesetting and "pst" like in Hipster. When writing about Typst, capitalize its name as a proper noun, with a capital "T".

Design Principles

All of Typst has been designed with three key goals in mind: Power, simplicity, and performance. We think it's time for a system that matches the power of LaTeX, is easy to learn and use, all while being fast enough to realize instant preview. To achieve these goals, we follow three core design principles:

  • Simplicity through Consistency: If you know how to do one thing in Typst, you should be able to transfer that knowledge to other things. If there are multiple ways to do the same thing, one of them should be at a different level of abstraction than the other. E.g. it's okay that = Introduction and #heading[Introduction] do the same thing because the former is just syntax sugar for the latter.

  • Power through Composability: There are two ways to make something flexible: Have a knob for everything or have a few knobs that you can combine in many ways. Typst is designed with the second way in mind. We provide systems that you can compose in ways we've never even thought of. TeX is also in the second category, but it's a bit low-level and therefore people use LaTeX instead. But there, we don't really have that much composability. Instead, there's a package for everything (\usepackage{knob}).

  • Performance through Incrementality: All Typst language features must accommodate for incremental compilation. Luckily we have comemo, a system for incremental compilation which does most of the hard work in the background.

svg2pdf's People

Contributors

eqt avatar frozolotl avatar laurenzv avatar laurmaedje avatar mrgalopes avatar reknih avatar rgreinho avatar ultraxime avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

svg2pdf's Issues

Masked SVG rendered inconsistently

Given the following SVG:

<svg id="svg1" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
    <title>Simple case</title>
    <mask id="mask1" mask-type="luminance">
        <rect id="rect1" x="0" y="0" width="200" height="200" fill="rgb(0 0 255)" opacity="1"/>
    </mask>
    <rect id="rect2" x="0" y="0" width="200" height="200" fill="rgb(255 0 0)" mask="url(#mask1)"/>
</svg>

Here is how they are rendered in different viewers:
mask_luminance-0

pdfium, pdf.js and pdfbox get the same output as Acrobat, while mupdf and Quartz get a slightly different output. Xpdf fails completely. So most likely a viewer issue, but would still be nice to investigate.

PDF content generated from SVG <pattern> jumps when zoom in/out in Safari

input.svg -> output.pdf

The expected behaviour is that the red line should be horizontally aligned with one of the blue lines (with the <pattern>). The output PDF looks as expected in Chrome and Preview apps but in Safari <pattern> jumps a bit up/down when changing the zoom level.

Is it something that can be fixed by modifying the SVG2PDF conversion flow? Since I could only reproduce this issue with <pattern> then maybe there is an alternative way of representing it before trying to create PDF? 🤔

`convert_tree_into` doesn't work

Following the example I get the error message

243  | svg2pdf::convert_tree_into(&tree, svg2pdf::Options::default(), &mut pdf, svg_id);
     | -------------------------- ^^^^^ expected `usvg_tree::Tree`, found `Tree`
     | |
     | arguments to this function are incorrect

If I replace &tree with usvg_tree::Tree::from(tree) I get

242 | svg2pdf::convert_tree_into(usvg_tree::Tree::from(tree), svg2pdf::Options::default(), &mut pdf, svg_id);
    | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&Tree`, found `Tree`
    | |
    | arguments to this function are incorrect

If I add a & I get

242  | svg2pdf::convert_tree_into(&usvg_tree::Tree::from(tree), svg2pdf::Options::default(), &mut pdf, svg_id);
     | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usvg_tree::Tree`, found `Tree`
     | |
     | arguments to this function are incorrect

Improve file size when embedding CFF fonts

The subsetter we currently use doesn't yield very great results for CFF-flavored fonts, meaning that PDFs can end up being pretty big when generating documents with such fonts. Subsetting CFF is unfortunately a major pain and will take a lot of time, so this will probably remain a problem for the next few months.

Compress content streams

As seen in typst/pdf-writer#5, sometimes the content stream this crate produces gets a bit large. Ultimately, the content streams should be compressed with miniz_oxide and marked as /Filter FlateDecode.

Grey scale PNG images

Consider the example image_qr.svg: the included PNG is a grey scale image. Hence in the resulting PDF in the ImageXObject header we correctly find

  /ColorSpace /DeviceGray

However, the pixel data is sampled in RGB (see and here) and therefore every pixel is repeated three times which looks strange.

line width/height defined with % is wrong

Trying to define lines with syntax like 100% generates output PDFs with wrong geometry:
<line x1="0" x2="100%" y1="10%" y2="10%" stroke="red"/>

height.svg -> height.pdf
width.svg -> width.pdf

How to reproduce: Input SVG's aspect ratio should be such that width > height to see the wrong width calculation <line x1="0" x2="100%>. In order to reproduce the height issue, use an SVG with height > width.

Workaround: Using rect with the same percentage-based syntax leads to correct width/height, as you can see from the attached examples.

Other SVG2PDF converters work fine with such syntax.

Existing font ignored

I have an SVG flyer which uses the "Dharma Gothic E" font. This font is installed correctly on my system (see screenshot):

image

However when I attempt a conversion with svg2pdf it falls back to another font.

Reproducible example

I just created a simple SVG using Inkscape. It renders correctly in the browser:

image

but not the PDF:

image

Here is the code of the SVG:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   width="74mm"
   height="52mm"
   viewBox="0 0 74 52"
   version="1.1"
   id="svg1"
   inkscape:version="1.3 (0e150ed, 2023-07-21)"
   sodipodi:docname="DharmaGothicE.svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <sodipodi:namedview
     id="namedview1"
     pagecolor="#ffffff"
     bordercolor="#000000"
     borderopacity="0.25"
     inkscape:showpageshadow="2"
     inkscape:pageopacity="0.0"
     inkscape:pagecheckerboard="0"
     inkscape:deskcolor="#d1d1d1"
     inkscape:document-units="mm"
     inkscape:zoom="2.0384855"
     inkscape:cx="374.54277"
     inkscape:cy="131.22487"
     inkscape:window-width="1392"
     inkscape:window-height="906"
     inkscape:window-x="2162"
     inkscape:window-y="389"
     inkscape:window-maximized="0"
     inkscape:current-layer="layer1" />
  <defs
     id="defs1">
    <rect
       x="71.271088"
       y="58.31271"
       width="165.21935"
       height="150.64117"
       id="rect1" />
  </defs>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <text
       xml:space="preserve"
       transform="scale(0.26458333)"
       id="text1"
       style="font-size:48px;white-space:pre;shape-inside:url(#rect1);fill:#000000"><tspan
         x="71.271484"
         y="252.74498"
         id="tspan6"><tspan
           dx="0 36.984375 30.375 28.828125 20.484375 46.6875"
           id="tspan5">Dharma</tspan></tspan></text>
    <text
       xml:space="preserve"
       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7px;font-family:Sans;-inkscape-font-specification:'Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.264583"
       x="59.11412"
       y="9.7057304"
       id="text2"><tspan
         sodipodi:role="line"
         id="tspan2"
         x="59.11412"
         y="9.7057304"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7px;font-family:'Dharma Gothic E';-inkscape-font-specification:'Dharma Gothic E, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;text-anchor:middle">Dharma </tspan><tspan
         sodipodi:role="line"
         x="59.11412"
         y="25.741634"
         id="tspan3"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7px;font-family:'Dharma Gothic E';-inkscape-font-specification:'Dharma Gothic E, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;text-anchor:middle">Gothic </tspan><tspan
         sodipodi:role="line"
         x="59.11412"
         y="41.777538"
         id="tspan4"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7px;font-family:'Dharma Gothic E';-inkscape-font-specification:'Dharma Gothic E, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;text-anchor:middle">E</tspan></text>
  </g>
</svg>

I also tried doing it as code, basically copy/pasting the code from the CLI, and then the text does not appear in the converted PDF.

But if I iterate through the fonts, I do see all my Dharma variants, like for instance:

FaceInfo {
    id: ID(
        InnerId(
            42v1,
        ),
    ),
    source: File(
        "../assets/fonts/DharmaGothicExtended copy/DharmaGothicE-Regular.otf",
    ),
    index: 0,
    families: [
        (
            "Dharma Gothic E",
            English_UnitedStates,
        ),
    ],
    post_script_name: "DharmaGothicE-Regular",
    style: Normal,
    weight: Weight(
        400,
    ),
    stretch: Normal,
    monospaced: false,
}

I did try with another font (Montserrat which is very common), and everything worked fine.

Is there something else I need to do to make it work? Do some fonts require some specific parameters or a special treatment?

Output has incorrect paper-size

The output-dimension of the svg after converting into a pdf is grown by factor ~1.33 .
svg2pdf::convert_tree(svg, Options::default());

Exporting the file by Inkscape creates a paper-size of 85 × 55 mm, doing it with the svg2pdf command-linetool creates a 113 × 73 mm.
For my project I need the accurate-result made by the printer.

May be a coincidence: factor 1.3333 is the difference between 72dpi and 96dpi

Embedded fonts have inconsistent text positions

Creating two simple text boxes next to each other in draw.io, exporting to SVG and converting to PDF with svg2pdf works fine. It does not work fine as soon as I select “Embed Fonts” when exporting to PDF, though. Apart from the text being rasterized (which might not be avoidable), the text is rendered at different heights.

  1. example.drawio:

    <mxfile host="Electron" modified="2024-02-05T13:57:42.198Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/23.0.2 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="U_0CKBYFzwEo-Qb8ycZV" version="23.0.2" type="device">
      <diagram name="Page-1" id="Cfz2YbFhdFfE50NHESyt">
        <mxGraphModel dx="133" dy="84" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
          <root>
            <mxCell id="0" />
            <mxCell id="1" parent="0" />
            <mxCell id="hu2bRimmB-T-eZgXSITk-1" value="Text" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;" vertex="1" parent="1">
              <mxGeometry x="170" y="185" width="60" height="30" as="geometry" />
            </mxCell>
            <mxCell id="hu2bRimmB-T-eZgXSITk-2" value="Text" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;" vertex="1" parent="1">
              <mxGeometry x="220" y="185" width="60" height="30" as="geometry" />
            </mxCell>
          </root>
        </mxGraphModel>
      </diagram>
    </mxfile>
  2. example.svg (with embedded fonts):

    example.svg

  3. example.pdf

Thanks for your help! :)

CLI compilation error

Compilation of feature cli fails with

error[E0609]: no field `fontdb` on type `usvg::Options`
  --> src/main.rs:41:13
   |
41 |     options.fontdb = fontdb::Database::new();
   |             ^^^^^^ unknown field
   |
   = note: available fields are: `resources_dir`, `dpi`, `font_family`, `font_size`, `languages` ... and 5 others

error[E0609]: no field `fontdb` on type `usvg::Options`
  --> src/main.rs:42:13
   |
42 |     options.fontdb.load_system_fonts();
   |             ^^^^^^ unknown field
   |
   = note: available fields are: `resources_dir`, `dpi`, `font_family`, `font_size`, `languages` ... and 5 others

error[E0599]: no function or associated item named `from_str` found for struct `Tree` in the current scope
  --> src/main.rs:44:21
   |
44 |         usvg::Tree::from_str(&svg, &options.to_ref()).map_err(|err| err.to_string())?;
   |                     ^^^^^^^^ function or associated item not found in `Tree`
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
   |
1  | use usvg::TreeParsing;
   |

error[E0599]: no method named `to_ref` found for struct `usvg::Options` in the current scope
  --> src/main.rs:44:45
   |
44 |         usvg::Tree::from_str(&svg, &options.to_ref()).map_err(|err| err.to_string())?;
   |                                             ^^^^^^ method not found in `Options`

Some errors have detailed explanations: E0599, E0609.
For more information about an error, try `rustc --explain E0599`.
error: could not compile `svg2pdf` due to 4 previous errors
error: failed to compile `svg2pdf v0.4.1 (https://github.com/typst/svg2pdf#6b9f5543)`, intermediate artifacts can be found at `/tmp/cargo-installORUKtb`

Example for `convert_tree_into` does not compile

The example for convert_tree_into fails to compile with the following error:

40  |     let tree = usvg::Tree::from_str(&svg, &usvg::Options::default()).unwrap();
    |                --------------------       ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&OptionsRef<'_>`, found `&Options`
    |                |
    |                arguments to this function are incorrect
    |

I'm using the depencies listed for version 0.4.1:

[dependencies]
pdf-writer = "0.6.0"
svg2pdf = "0.4.1"
usvg = "0.22.0"

I tried updating all crates:

[dependencies]
pdf-writer = "0.7.1"
svg2pdf = "0.4.1"
usvg = "0.33.0"

But then it seems there's a mismatch between types when compiling:

    |
47  |     svg2pdf::convert_tree_into(&tree, svg2pdf::Options::default(), &mut writer, svg_id);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^                                     -----------  ------ expected `pdf_writer::object::Ref`, found `pdf_writer::Ref`
    |                                                                    |
    |                                                                    expected `pdf_writer::PdfWriter`, found `PdfWriter`
    |

Could the library be updated to work with last versions of pdf-writer and usvg available?

Make converted SVGs use up less space

Currently, in cases of bigger SVGs, svg2pdf will often create SVGs that take up much more space than they should.

Consider the following SVG:
test2

The SVG itself is 770KB. Once converted with svg2pdf, it takes about 568KB of space. However, cloud converters manage to get it down to around ~220KB.

The reason for that is twofold: One the one hand, we create way too many XObjects, meaning that we can't make full use of the compression using Deflate. Not only that, but we also sometimes create XObject that are completely empty. Here is an example from the SVG above:

12 0 obj
<<
  /Length 3
  /Type /XObject
  /Subtype /Form
  /Resources <<
    /ColorSpace <<
      /srgb [/CalRGB <<
        /WhitePoint [0.9505 1 1.0888]
        /Gamma [2.2 2.2 2.2]
        /Matrix [0.4124 0.2126 0.0193 0.3576 0.715 0.1192 0.1805 0.0722 0.9505]
      >>]
    >>
    /ProcSet [/PDF /ImageC /ImageB]
  >>
  /Group <<
    /Type /Group
    /S /Transparency
    /I true
    /K false
    /CS [/CalRGB <<
      /WhitePoint [0.9505 1 1.0888]
      /Gamma [2.2 2.2 2.2]
      /Matrix [0.4124 0.2126 0.0193 0.3576 0.715 0.1192 0.1805 0.0722 0.9505]
    >>]
  >>
  /BBox [46.428413 367 545.4284 966]
  /Matrix [0.18334149 0 0 0.18334149 163.40727 -242.72272]
>>
stream
q
Q
endstream
endobj

Something like this could be avoided if we checked wether a usvg::Group actually contains paths/children before creating an XOBject for that. However, the main issue is still that we have so many XObjects which all have the Group and ColorSpace entry. which bloats the PDF unnecessarily.

Some things we could do to improve this:

  • Improvements in pdf-writer: I think there are a couple of improvements we could implement in pdf-writer to make files smaller. For example, just by removing the indent feature, I was able to get the file down from 568KB to 526KB. The PDF looks a bit uglier this way when opening it in a text editor, but this shouldn't really be a concern, since they are not meant to be read by humans anyway.
  • Before creating an XObject, check whether it actually contains paths that need to be drawn.
  • Only add the ColorSpace and Transparency Group attributes to XObjects that actually need it. This will require some thinking, but it will improve the space requirements by a lot.
  • Avoid allocating so many XObjects. This will be the most difficult part to implement, as it will require us to keep track of some transformations in svg2pdf and resorting to mainly using the cm operator to apply transformations instead of relying on the Matrix attribute of XObjects. But this will make everything much more space efficient. And if we manage to implement this, the 4 points mentioned above could probably be completely ignored as they won't have such a big effect anymore.

CLI: Image transformation not being applied, and text not loading despite being system fonts

I have a simple SVG which contains an embedded jpg image transformed so that it fits the height of the svg document, as well as an embedded svg which is text using the system font Verdana in the middle. But running svg2pdf loses the transform and also loses the text.

Steps to reproduce:

  1. Save the attached svg as assets/svg_test.svg
  2. run svg2pdf ./assets/svg_test.svg ./assets/svg_test.pdf

Expected Result:
The PDF should render the embedded image properly fitted onto the 1920x1080p canvas, and the text should be rendered in the middle

Actual Result:
The image is no longer transformed to fit the canvas, and the text is missing


Format of svg_test.svg

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="1920" width="1080">
<image height="100%" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZ...REST_OF_IMAGE_DATA" preserveAspectRatio="xMidYMid slice"/>
    <svg height="1920" width="1080" x="0" y="0">
        <text fill="#ffffff" font-family="Verdana" font-size="35" font-weight="bold" text-anchor="middle" x="50%" y="50%">Hello World</text>
    </svg>
</svg>

THE ORIGINAL svg_test.svg
svg_test

The faulty output I got:
svg_test.pdf

Multiple pages

Sorry to ask a question here. Is it possible to split a SVG into multiple PDF pages? If not is support for this feature planned in the future?

Text element support

Thanks for creating svg2pdf! Does it support text elements? I get a blank PDF when I try to convert the following SVG:

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     width="600" height="300">
<text x="0" y="15" fill="red">I love SVG</text>
</svg>

Error in `dpi_ratio`

Hello,

I was trying to convert a 1500x2300 pixels SVG into a PDF using svg2pdf.
I want it to be 62.7x96.2mm. So by simple math, it should be at a resolution around 607dpi.
But while reading the output, my PDF reader (okular and brave) told me it was 4461x6840mm.
Using the trial and error method, I found that the dpi I had to provide to svg2pdf was 8.5.

So dug into the code to find where I could have made a mistake, or it was svg2pdf that had one.

It seems to me that line 396 and 397 in lib.rs you multiply by dpi_ratio instead of dividing by it.
dpi_ratio is defined in util.helper.rs as dpi / 72. I understand the user unit in PDF is 1/72nd of an inch, hence the division by 72.
So dpi_ratio returns a value in dots per inch time inch per user unit, i.e. dots per user unit.
Hence, multiply dots by dots per user unit gave us dot² per user unit instead of user unit.

If I made a mistake in my reasoning, and I'm wrong, I would be happy to be corrected; else I can either make a pull request with the modification, or wait for you to correct it.

Add support for better font fallback

There have been numerous issues (e.g. #43 #44 #63) where people have had issues with text not showing up. Those are all very likely because the exact font isn't installed on the system (or isn't found) and font fallback fails to find another appropriate one.

Since we have logging support now, we should at least get warnings if that happens, but in the end we still need better fallback support. However, since text conversion is done by usvg, there isn't much we can do from our side for now...

Colors are not represented accurately

Consider the following SVG:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
        "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1" >
  <rect x="0" y="0" width="200" height="200" fill="#111122" />

</svg>

The output color will look much darker (approximately rgb(6, 6, 29) instead of rgb(17, 17, 34)) than it should be.

We should change to using ICCProfiles to make colors more accurate.

More CLI options

Right now, I'm trying to convert a very tall SVG (2779 width by 32576 height at 96 dpi) to a multi-page PDF, but there seems to be no command line options to adjust the page size or add splits.

Embed text rather than converting text to paths

Hi, it looks like usvg 0.28.0 recently added the ability to avoid converting text to paths during the simplification process: https://github.com/RazrFalcon/resvg/blob/master/CHANGELOG.md.

I was hoping this would open the possibility of having svg2pdf do the same, by embedding text in the resulting PDF rather than converting text to paths.

For context, I'd be interested in using svg2pdf to add PDF support to the VlConvert Rust library (which already supports SVG and uses resvg for PNG support). But having true text embedded in the resulting PDF is important for accessibility. Thanks!

Weird behavior when embedding image in SVG and specifying width/height in a unit other than px

I wanted to do some digging into this issue, and at least one part of the problem can be reduced to the following weird behavior:

The first thing I did is to create a 50px x 50px image of a yellow rectangle and I tried to generate two different SVGs:

Version 1

I first tried the following SVG.

Input:

<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100" viewBox="0 0 100 100"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
    <image xlink:href="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAQ0lEQVR42u3PQREAAAgDINc/9Mzg14MGpJ3OAxERERERERERERERERERERERERERERERERERERERERERERERERERuVjg6JWdCD2ogQAAAABJRU5ErkJggg=="
           id="image7eea7a0a44"/>
</svg>

which correctly is outputted as the following:

Output:
image

Version 2

Now comes the weird thing though, if I specify the width and height of the SVG itself in pt but leave the view box unchanged, I get the following result.

Input:

<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="100pt" height="100pt" viewBox="0 0 100 100"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
    <image xlink:href="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAQ0lEQVR42u3PQREAAAgDINc/9Mzg14MGpJ3OAxERERERERERERERERERERERERERERERERERERERERERERERERERuVjg6JWdCD2ogQAAAABJRU5ErkJggg=="
           id="image7eea7a0a44"/>
</svg>

Output:
image

So for some reason, the image is shifted down a bit and it's a bit too small. If I render the same svg in resvg, it looks like in Version 1.

I'll try to figure out what's going on, but I thought I'd post this anyways in case someone already knows what might be the problem here.

svg input differs to pdf output

I thought you might be interested. I am currently creating .svg files using Poloto and was wondering why my plots suddenly become informationless when I save them as .pdf. You can have a look at the files from my gitlab project for comparison. The .svg were first translated with your library and then again with inkscape. So from my point of view you are just as good as inkscape at translating .svg to .pdf.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.