Skip to content
Open
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,9 @@ var options = new ResvgOptions
| `ExportId` | `string?` | `null` | Export specific element by ID |
| `ExportAreaPage` | `bool` | `false` | Export page area |
| `ExportAreaDrawing` | `bool` | `true` | Export drawing area |
| `ResourcesDir` | `string?` | `null` | Resources directory path |
| `ResourcesDir` | `string?` | `null` | Resources directory path |
| `SerifFamily` | `string?` | `null` | Sets the 'serif' font family |
| `SansSerifFamily` | `string?` | `null` | Sets the 'sans-serif' font family |
| `CursiveFamily` | `string?` | `null` | Sets the 'cursive' font family |
| `FantasyFamily` | `string?` | `null` | Sets the 'fantasy' font family |
| `MonospaceFamily` | `string?` | `null` | Sets the 'monospace' font family |
30 changes: 30 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ public class ResvgOptions
/// Directory used for resolving relative paths in the SVG.
/// </summary>
public string? ResourcesDir { get; set; }

/// <summary>
/// Sets the 'serif' font family.
/// </summary>
public string? SerifFamily { get; set; }

/// <summary>
/// Sets the 'sans-serif' font family.
/// </summary>
public string? SansSerifFamily { get; set; }

/// <summary>
/// Sets the 'cursive' font family.
/// </summary>
public string? CursiveFamily { get; set; }

/// <summary>
/// Sets the 'fantasy' font family.
/// </summary>
public string? FantasyFamily { get; set; }

/// <summary>
/// Sets the 'monospace' font family.
/// </summary>
public string? MonospaceFamily { get; set; }
}
```

Expand All @@ -124,6 +149,11 @@ pub struct RenderOptions {
pub font_count: usize, // number of fonts
pub font_file: *const c_char, // null for unset
pub font_dir: *const c_char, // null for unset
pub serif_family: *const c_char, // null for unset
pub sans_serif_family: *const c_char, // null for unset
pub cursive_family: *const c_char, // null for unset
pub fantasy_family: *const c_char, // null for unset
pub monospace_family: *const c_char, // null for unset
}

#[no_mangle]
Expand Down
27 changes: 26 additions & 1 deletion native/resvg-wrapper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ pub struct RenderOptions {
pub font_count: usize,
pub font_file: *const c_char,
pub font_dir: *const c_char,
pub serif_family: *const c_char,
pub sans_serif_family: *const c_char,
pub cursive_family: *const c_char,
pub fantasy_family: *const c_char,
pub monospace_family: *const c_char,
}

unsafe fn c_str_to_string(ptr: *const c_char) -> Option<String> {
Expand Down Expand Up @@ -74,7 +79,27 @@ pub extern "C" fn render_svg_to_png_with_options(
if let Some(font_dir) = c_str_to_string(opts.font_dir) {
fontdb.load_fonts_dir(&font_dir);
}


if let Some(serif_family) = c_str_to_string(opts.serif_family) {
fontdb.set_serif_family(&serif_family);
}

if let Some(sans_serif_family) = c_str_to_string(opts.sans_serif_family) {
fontdb.set_sans_serif_family(&sans_serif_family);
}

if let Some(cursive_family) = c_str_to_string(opts.cursive_family) {
fontdb.set_cursive_family(&cursive_family);
}

if let Some(fantasy_family) = c_str_to_string(opts.fantasy_family) {
fontdb.set_fantasy_family(&fantasy_family);
}

if let Some(monospace_family) = c_str_to_string(opts.monospace_family) {
fontdb.set_monospace_family(&monospace_family);
}

let mut usvg_opts = Options::default();
usvg_opts.fontdb = std::sync::Arc::new(fontdb);

Expand Down
62 changes: 61 additions & 1 deletion src/ResvgSharp/Resvg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ private struct RenderOptions
public UIntPtr font_count;
public IntPtr font_file;
public IntPtr font_dir;
public IntPtr serif_family;
public IntPtr sans_serif_family;
public IntPtr cursive_family;
public IntPtr fantasy_family;
public IntPtr monospace_family;
}

[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -68,7 +73,12 @@ public static byte[] RenderToPng(string svg, ResvgOptions? options = null)
font_lens = IntPtr.Zero,
font_count = UIntPtr.Zero,
font_file = IntPtr.Zero,
font_dir = IntPtr.Zero
font_dir = IntPtr.Zero,
serif_family = IntPtr.Zero,
sans_serif_family = IntPtr.Zero,
cursive_family = IntPtr.Zero,
fantasy_family = IntPtr.Zero,
monospace_family = IntPtr.Zero,
};

IntPtr backgroundPtr = IntPtr.Zero;
Expand All @@ -79,6 +89,11 @@ public static byte[] RenderToPng(string svg, ResvgOptions? options = null)
IntPtr[] fontPtrs = Array.Empty<IntPtr>();
IntPtr fontArrayPtr = IntPtr.Zero;
IntPtr fontLensPtr = IntPtr.Zero;
IntPtr serifFamilyPtr = IntPtr.Zero;
IntPtr sansSerifFamilyPtr = IntPtr.Zero;
IntPtr cursiveFamilyPtr = IntPtr.Zero;
IntPtr fantasyFamilyPtr = IntPtr.Zero;
IntPtr monospaceFamilyPtr = IntPtr.Zero;

try
{
Expand Down Expand Up @@ -122,6 +137,46 @@ public static byte[] RenderToPng(string svg, ResvgOptions? options = null)
nativeOptions.font_dir = fontDirPtr;
}

if (!string.IsNullOrEmpty(options.SerifFamily))
{
var serifFamilyBytes = System.Text.Encoding.UTF8.GetBytes(options.SerifFamily + "\0");
serifFamilyPtr = Marshal.AllocHGlobal(serifFamilyBytes.Length);
Marshal.Copy(serifFamilyBytes, 0, serifFamilyPtr, serifFamilyBytes.Length);
nativeOptions.serif_family = fontDirPtr;
}

if (!string.IsNullOrEmpty(options.SansSerifFamily))
{
var sansSerifFamilyBytes = System.Text.Encoding.UTF8.GetBytes(options.SansSerifFamily + "\0");
sansSerifFamilyPtr = Marshal.AllocHGlobal(sansSerifFamilyBytes.Length);
Marshal.Copy(sansSerifFamilyBytes, 0, sansSerifFamilyPtr, sansSerifFamilyBytes.Length);
nativeOptions.sans_serif_family = sansSerifFamilyPtr;
}

if (!string.IsNullOrEmpty(options.CursiveFamily))
{
var cursiveFamilyBytes = System.Text.Encoding.UTF8.GetBytes(options.CursiveFamily + "\0");
cursiveFamilyPtr = Marshal.AllocHGlobal(cursiveFamilyBytes.Length);
Marshal.Copy(cursiveFamilyBytes, 0, cursiveFamilyPtr, cursiveFamilyBytes.Length);
nativeOptions.cursive_family = cursiveFamilyPtr;
}

if (!string.IsNullOrEmpty(options.FantasyFamily))
{
var fantasyFamilyBytes = System.Text.Encoding.UTF8.GetBytes(options.FantasyFamily + "\0");
fantasyFamilyPtr = Marshal.AllocHGlobal(fantasyFamilyBytes.Length);
Marshal.Copy(fantasyFamilyBytes, 0, fantasyFamilyPtr, fantasyFamilyBytes.Length);
nativeOptions.fantasy_family = fantasyFamilyPtr;
}

if (!string.IsNullOrEmpty(options.MonospaceFamily))
{
var monospaceFamilyBytes = System.Text.Encoding.UTF8.GetBytes(options.MonospaceFamily + "\0");
monospaceFamilyPtr = Marshal.AllocHGlobal(monospaceFamilyBytes.Length);
Marshal.Copy(monospaceFamilyBytes, 0, monospaceFamilyPtr, monospaceFamilyBytes.Length);
nativeOptions.monospace_family = monospaceFamilyPtr;
}

if (options.UseFonts != null && options.UseFonts.Length > 0)
{
fontPtrs = new IntPtr[options.UseFonts.Length];
Expand Down Expand Up @@ -197,6 +252,11 @@ public static byte[] RenderToPng(string svg, ResvgOptions? options = null)
if (resourcesDirPtr != IntPtr.Zero) Marshal.FreeHGlobal(resourcesDirPtr);
if (fontFilePtr != IntPtr.Zero) Marshal.FreeHGlobal(fontFilePtr);
if (fontDirPtr != IntPtr.Zero) Marshal.FreeHGlobal(fontDirPtr);
if (serifFamilyPtr != IntPtr.Zero) Marshal.FreeHGlobal(serifFamilyPtr);
if (sansSerifFamilyPtr != IntPtr.Zero) Marshal.FreeHGlobal(sansSerifFamilyPtr);
if (cursiveFamilyPtr != IntPtr.Zero) Marshal.FreeHGlobal(cursiveFamilyPtr);
if (fantasyFamilyPtr != IntPtr.Zero) Marshal.FreeHGlobal(fantasyFamilyPtr);
if (monospaceFamilyPtr != IntPtr.Zero) Marshal.FreeHGlobal(monospaceFamilyPtr);

foreach (var ptr in fontPtrs)
{
Expand Down
10 changes: 10 additions & 0 deletions src/ResvgSharp/ResvgOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,14 @@ public class ResvgOptions
public bool ExportAreaDrawing { get; set; } = true;

public string? ResourcesDir { get; set; }

public string? SerifFamily { get; set; }

public string? SansSerifFamily { get; set; }

public string? CursiveFamily { get; set; }

public string? FantasyFamily { get; set; }

public string? MonospaceFamily { get; set; }
}