Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing document generation #1151

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/builddocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ name: DocBuild
# Trigger the action on push to master
on:
push:
branches:
branches:
- master
- doc-3.4.7

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
Expand Down
109 changes: 109 additions & 0 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
## Getting the library

Depending on the way you want to work with the library you can get the SVG library via NuGet, or roll your own binary from the sources or a personal fork of the sources.

### Which version to choose?
There are 2 major supported versions at the moment: version `2.4.*` and version `3.0.*`. Version `2.4.*` is a .NET Framework specific version (non .NET Core compatible)
which can be considered rather stable for use within a .NET project.
The `3.0` version is a more recent version with added .NET Core compatibility and the possibility to run the package in .NET Core projects under Windows, Linux and MacOs.
The .NET framework compatibility is also maintained, which allows you to use the package in the regular .NET framework (version 3.5 and above).
The `3.0` version also contains some bugfixes which are not (yet) in the `2.4` version,
but this is a limited set and if required these fixes can be merged into the `2.4` version on request.

If you are going to use the package for the first time, your best bet is to go for the `3.0.*` version - this allows for maximum flexibility and portability.
If you are already using version `2.4` or use other libraries depending on the `2.4` versions you can also upgrade,
but there is a possibility that you might encounter compatibility issues/errors.
The library is unit tested, but it cannot be guaranteed that versions `3.0` and `2.4` behave completely the same.
If you are working with the .NET framework version you are likely to encounter no big issues, but if you switch to the .NET Core version or switch platforms
(e.g. to MacOs or Linux) you need to test and validate the calling code to be sure everything keeps working as expected.

### Installing via NuGet
The library is available as a NuGet package in the public NuGet feed (https://www.nuget.org/packages/Svg/).
Depending on your development stack you can add it to your code base.

For Visual Studio 2013 - 2019 you can add it by searching it in the NuGet wizard or by using the following command in the NuGet Console:
```
Install-Package Svg
```

When using the .NET command line client (`dotnet-cli`), you can add the package to your solution by running the following command in the terminal/console:
```
dotnet add package Svg
```

If you would like to add a specific version you can add the `--version` parameter to your command or pick a specific version in the wizard.
If you want to use pre-release versions in Visual Studio you need to check the box regarding pre-release packages to be able to select pre-release versions.

### Rolling your own version
If you would like to roll your own version you can download the sources via GitHub, clone the repository to your local machine,
or create a fork in your own account and download/clone this to your machine. This will give you more flexibility in choosing the target framework(s) and compiler flags.

Once you downloaded the sources you can use the IDE of your choice to open the solution file (`Svg.sln`) or the Svg library project (`Svg.csproj`)
and use your IDE to compile the version you would like to have.

If you would like to use `dotnet-cli` to build the sources you can use the following command in the `Sources/` folder to build the library
for .NET Core 3.1 with the compiler setting for release:
```
dotnet build -c release -f netcoreapp3.1 Svg.csproj
```
This will put the output into the `bin/Release/netcoreapp3.1/` folder.

## Special instructions for Mac and Linux
The library depends on GDI+ (see also [here](http://svg-net.github.io/SVG/doc/Q&A.html#im-getting-a-svggdipluscannotbeloadedexception-if-running-under-linux-or-macos)) for rendering.
.NET Core does not support GDI+ out of the box for non-Windows systems. For Mac and Linux you need to add a special compatibility package.
This is not included in the packages by default, since this would break rendering on Windows systems.

I you distribute your application as platform independent, you might want to add the following instructions (or a reference to this guide)
in your installation instructions to aid Mac and Linux users that want to utilize your application/library.

### Linux (Ubuntu)
For Linux you need to install `libgdiplus` from the `quamotion/ppa` feed on your machine/container:
```
sudo add-apt-repository ppa:quamotion/ppa
sudo apt-get update
sudo apt-get install -y libgdiplus
```

### MacOs
MacOs does not require you to install a system-wide package, but allows you to use a compatibility package that is included in the application.
This package can be included in the SVG component if you roll your own version from source.
This can be achieved by altering the `Svg.csproj` file and un-comment the following block of code:
```
<!--
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="5.8.64" />
</ItemGroup>
-->
```
This will link the `CoreCompat` package in the project.
If you make a project reference to `Svg.csproj` the consuming application/library will automatically also include the `CoreCompat` package.

If you are not building from source or do not want to make the Svg library dependent on the `CoreCompat` package,
you can add the reference in the "ultimate" consumer of the package (the application that will be executed),
by the following command in a terminal/console within the consuming application folder:
```
dotnet add package runtime.osx.10.10-x64.CoreCompat.System.Drawing
```

## Linking the library in your application
If you have installed or built the library, it's time to add it to your application.
If you used the NuGet approach, the reference should already be set correctly (please note that for Mac and Linux the compatibility tooling/package needs to be done manually).

If you rolled your own version, you can link the `.csproj` to your own project via your IDE. If you want to do it through `dotnet-cli` you can run:
```
dotnet add reference SVG/sources/Svg.csproj
```
(where SVG is the root folder you downloaded the sources to).
This approach will also take over all references required to the target project (e.g. when you added the `CoreCompat` package for Mac).
This will also compile the Svg sources when you build your own project, which might be useful if you plan to make changes in the Svg project yourself.

If you don't want to reference the project, you can get the `Svg.dll` file from the outpot folders after you compiled the project with the steps outlined above and reference it.
The Svg library does not utilize other external references under Windows, and by only using the `Svg.dll` file you will be able to use the library.
However please keep in mind that the Mac and Linux versions require additional tooling/packages.

## Using the library (examples)
This part will be extended in the future, for now please refer to the [Q&A](http://svg-net.github.io/SVG/doc/Q&A.html) for examples of how to use the library.

## Troubleshooting
If you encounter any problems or difficulties, please refer to the [Q&A part of the documentation](http://svg-net.github.io/SVG/doc/Q&A.html).
If the Q&A does not solve your problem, please open a ticket with your request.
150 changes: 150 additions & 0 deletions docs/Q&A.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
This is currently a collection of answered questions in issues that have been closed meanwhile.
The format of the page is preliminary and maybe changed if more questions accumulate.

## How to get started
Please use our [getting started article](http://svg-net.github.io/SVG/doc/GettingStarted.html) to get started with installation and implementation of the SVG library.

## How to re-render an SVG faster?

(from [#327](https://github.com/svg-net/SVG/issues/327), by @flemingtech)

The rendering type plays a significant role on rendering speeds. For example, if anti-aliasing is off for the SvgDocument render times are notably faster.

Because of the huge reduction in image quality, this wasn't a viable solution for my needs. Instead what I've come up with so far seems to work since I can't figure out how to get clipping regions to work.

After I load the SVG, I make new SVG with the same initial SvgDocument properties (basically a deep copy followed by deleting all children). As I walk the first document tree I'm looking for elements I know are going to be modified. For each one that I find, I remove it from the first SVG and put it into the 2nd SVG. When I'm doing this, I also apply any parent transforms to the new child since it doesn't need/have all of it's parents.

Once I'm done, I render the first SVG to an Image. When any of the 'animating' elements are changed, the 2nd SVG is rendered on top of a copy of the first SVG's rendering to form a complete composite. This prevents all the non-moving elements for having to re-render, unless of course the target graphics width/height changes. This is giving huge performance gains.

## Can I use SVG.NET in a UWP Windows 10 App?

(from [#219](https://github.com/svg-net/SVG/issues/219), by @jonthysell)

SVG.NET requires the System.Drawing namespace, which is not available in UWP. See http://stackoverflow.com/questions/31545389/windows-universal-app-with-system-drawing-and-possible-alternative.

## How to render an SVG image to a single-color bitmap image?

(from [#366](https://github.com/svg-net/SVG/issues/366), by @UweKeim)

I was able to find a solution with the following fragment:

```csharp
var svgDoc = SvgDocument.Open<SvgDocument>(svgFilePath, null);

// Recursively change all nodes.
processNodes(svgDoc.Descendants(), new SvgColourServer(Color.DarkGreen));

var bitmap = svgDoc.Draw();
```

together with this function:

```csharp
private void processNodes(IEnumerable<SvgElement> nodes, SvgPaintServer colorServer)
{
foreach (var node in nodes)
{
if (node.Fill != SvgPaintServer.None) node.Fill = colorServer;
if (node.Color != SvgPaintServer.None) node.Color = colorServer;
if (node.StopColor != SvgPaintServer.None) node.StopColor = colorServer;
if (node.Stroke != SvgPaintServer.None) node.Stroke = colorServer;

processNodes(node.Descendants(), colorServer);
}
}
```

## How to render only a specific SvgElement?

(from [#403](https://github.com/svg-net/SVG/issues/403), by @ievgennaida)

Use `element.RenderElement();`.

## How to render an SVG document to a bitmap in another size?

Use `SvgDocument.Draw(int rasterWidth, int rasterHeight)`. If one of the values is 0, it is set to preserve the aspect ratio, if both values are given, the aspect ratio is ignored.

## Is this code server-safe?

(from [#381](https://github.com/svg-net/SVG/issues/381), by @rangercej, answered by @gvheertum)

I used it in server side code (ASP.NET MVC application and API's) and never had any problems with it. There is however be possible issues regarding use in services and API's, for example the System.Drawing might not always be available in certain situations (if I am not mistaken, some Azure service will not provide the System.Drawing since it relies on GDI calls) and will also be an issue when using it as "portable" code for example in .NET standard or .NET core (but I believe the library is already working on a migration/compatibility with .NET core/standard).

So issues when using System.Drawing are indeed possible when using in a non interactive scenario, since most non-interactive code will often be functioning as service or API, meaning a lot of synchronous calls are possible, which opens a world of possible problems compared to an interactive app which you often only have a few instances loaded. System.Drawing can (and often will) be resource-heavy, so having a lot of synchronous processes will possibly have a huge impact on the performance. So I guess, that is why Microsoft warns about the usage. Rendering a large complex SVG to a big bitmap (eg 5000x5000px) will put a large load on the server, doing this in parallel might cause issues in performance and availability.

System.Drawing was initially not really created for service usage, so you *can* use it, but really need to be aware of possible issues. For example, see this article: https://photosauce.net/blog/post/5-reasons-you-should-stop-using-systemdrawing-from-aspnet

I believe there are some parallelisation tests in the UnitTest suite, since the SVG component did have some concurrency issues in the past. The parallelisation tests show that some parallel work is possible, but upping the limit will show you that resource issues are to be expected under large loads. When failing, System.Drawing will often not fail gracefully, but will often crash with some meaningless error (which makes debugging pretty hard sometimes).

## How to change the SvgUnit DPI?

(from [#313](https://github.com/svg-net/SVG/issues/313), by @KieranSmartMP)

`SvgUnit` takes the DPI (which is called `Ppi` here) from the document. This is set to the system DPI at creation time, but can be set to another value afterwards, e.g.
```c#
doc = SvgDocument();
doc.Ppi = 200;
...
```

## Why does my application crash with "cannot allocate the required memory"?

(from [#250](https://github.com/svg-net/SVG/issues/250), by @Radzhab)

If you try to open a very large SVG file in your application, it may crash, because .NET refuses to allocate that much contiguous memory, even if it could do so in theory. This is done to avoid processes to consume too much memory and slow down the system. Nothing we can do about this - you may catch this exception in your application and inform the user, or try to resize your SVG document and retry.

## How to add a custom attribute to an SVG element?

(from [#481](https://github.com/svg-net/SVG/issues/481), by @lroye)

Custom attributes are publicly accessible as a collection, you can add an attribute like this:
```C#
element.CustomAttributes[attributeName] = attributeValue;
```

## I'm getting a SvgGdiPlusCannotBeLoadedException if running under Linux or MacOs

(see [#494](https://github.com/svg-net/SVG/pull/495#issuecomment-505429874), by @ErlendSB)

This happens if libgdiplus is not installed under Linux or MacOs - libgdiplus is need for the implementation of System.Drawing.Common. The system will validate gdi+ capabilities when calling SvgDocument.Open(), if the gdi+ capabilities are not available, you will receive a SvgGdiPlusCannotBeLoadedException.

There is a [packaging project on Github](https://github.com/CoreCompat/libgdiplus-packaging) that helps installing that, here are the installation instructions (copied here for convenience):

Older versions of the package threw a NullReferenceException when calling the SvgDocument.Open function. The cause of these errors was the same. Newer releases (since version 3.0), will yield a more descriptive exception as described above.

### Using libgdiplus on Ubuntu Linux

You can install libgdiplus on Ubuntu Linux using the Quamotion PPA. Follow these steps:
```
sudo add-apt-repository ppa:quamotion/ppa
sudo apt-get update
sudo apt-get install -y libgdiplus
```
### Using libgdiplus on macOS

On macOS, add a reference to the runtime.osx.10.10-x64.CoreCompat.System.Drawing package:

```dotnet add package runtime.osx.10.10-x64.CoreCompat.System.Drawing```

When building from source-code you can also uncomment the
```
<!-- <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="5.6.20" />
</ItemGroup> -->
```
block in the Svg.csproj file.

### Validating GDI+ capabilities

If you want to make sure the executing system is capable of using the GDI+ features, you can use one of the functions available on the SvgDocument class.

If you only want to get a boolean telling whether the capabilities are available, please use the following code:
```
bool hasGdiCapabilities = SvgDocument.SystemIsGdiPlusCapable();
```

If you want to ensure the capabilities and let an error be thrown when these are not available, please use the following code:
```
SvgDocument.EnsureSystemIsGdiPlusCapable();
```
This function will throw a SvgGdiPlusCannotBeLoadedException if the capabilities are not available.
Loading