diff --git a/examples/utf-8/стекло/있어요/ext-utf8-4.cir b/examples/utf-8/стекло/있어요/ext-utf8-4.cir
index 5b0bdeef5..653068ff1 100644
--- a/examples/utf-8/стекло/있어요/ext-utf8-4.cir
+++ b/examples/utf-8/стекло/있어요/ext-utf8-4.cir
@@ -1,6 +1,6 @@
* test de titré それは私を傷つけません
.control
-set hcopydevtype = postscript
+set hcopydevtype = svg
set hcopypscolor=1
*set hcopyscale=0.5
set color2=rgb:FF/0/0
@@ -9,7 +9,7 @@ set color2=rgb:FF/0/0
if $oscompiled = 2
setcs hcopyfont='NimbusMono-Regular'
end
-set hcopyfontsize=14
+set hcopyfontsize=18
* for CYGWIN
setcs xfont='Noto Sans CJK JP Medium'
@@ -23,16 +23,24 @@ plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜ
plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 22 أنا قادر على أكل الزجاج و هذا لا يؤلمني.'
plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 23 私はガラスを食べられます。それは私を傷つけません' loglog
plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 24 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog
+
+set xbrushwidth=6
+set xgridwidth=2
+setcs hcopyfont=Arial
+setcs hcopyfontfamily=Arial
+hardcopy plot_4.svg y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 24 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog
+
* for CYGWIN
if $oscompiled = 2
setcs xfont='Times New Roman'
end
plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 25' loglog
-hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~'
+hardcopy plot_5.svg y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~'
* for MS Windows only
if $oscompiled = 1 | $oscompiled = 8
- shell Start /B plot_5.ps
+ shell Start /B plot_4.svg
+ shell Start /B plot_5.svg
* for CYGWIN
else
shell xterm -e gs plot_5.ps &
diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am
index 2ebd79e19..4786522be 100644
--- a/src/frontend/Makefile.am
+++ b/src/frontend/Makefile.am
@@ -177,6 +177,8 @@ libfte_la_SOURCES = \
spiceif.h \
subckt.c \
subckt.h \
+ svg.c \
+ svg.h \
typesdef.c \
typesdef.h \
vectors.c \
diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c
index 9d62fcf10..7f00a6c90 100644
--- a/src/frontend/com_hardcopy.c
+++ b/src/frontend/com_hardcopy.c
@@ -77,17 +77,34 @@ void com_hardcopy(wordlist *wl)
return;
}
- /* change .tmp to .ps */
- psfname = strchr(fname, '.');
- if (psfname) {
- psfname[1] = 'p';
- psfname[2] = 's';
- psfname[3] = '\0';
+ if (!strcmp(devtype, "svg")) {
+ /* change .tmp to .svg */
+ psfname = strchr(fname, '.');
+ if (psfname) {
+ psfname[1] = 's';
+ psfname[2] = 'v';
+ psfname[3] = 'g';
+ psfname[4] = '\0';
+ }
+ else {
+ fname = trealloc(fname, n_byte_fname + 4);
+ (void)memcpy(fname + n_byte_fname - 1, ".svg", 5);
+ n_byte_fname += 4;
+ }
}
else {
- fname = trealloc(fname, n_byte_fname + 3);
- (void) memcpy(fname + n_byte_fname - 1, ".ps", 4);
- n_byte_fname += 3;
+ /* change .tmp to .ps */
+ psfname = strchr(fname, '.');
+ if (psfname) {
+ psfname[1] = 'p';
+ psfname[2] = 's';
+ psfname[3] = '\0';
+ }
+ else {
+ fname = trealloc(fname, n_byte_fname + 3);
+ (void)memcpy(fname + n_byte_fname - 1, ".ps", 4);
+ n_byte_fname += 3;
+ }
}
tempgraph->devdep = fname;
tempgraph->n_byte_devdep = n_byte_fname;
@@ -225,6 +242,11 @@ void com_hardcopy(wordlist *wl)
"\nThe file \"%s\" may be printed on a postscript printer.\n",
fname);
}
+ else if (!strcmp(devtype, "svg")) {
+ fprintf(cp_out,
+ "\nThe file \"%s\" has the Scalable Vector Graphics format.\n",
+ fname);
+ }
else if (!strcmp(devtype, "MFB")) {
fprintf(cp_out,
"The file \"%s\" may be printed on a MFB device.\n",
diff --git a/src/frontend/display.c b/src/frontend/display.c
index 9ad29be0a..56f5589bc 100644
--- a/src/frontend/display.c
+++ b/src/frontend/display.c
@@ -36,7 +36,7 @@ static int nodev(void);
#include "plotting/plot5.h"
#include "postsc.h"
#include "hpgl.h"
-
+#include "svg.h"
DISPDEVICE device[] = {
@@ -110,6 +110,15 @@ DISPDEVICE device[] = {
(disp_fn_Track_t *) nodev, (disp_fn_MakeMenu_t *) nodev, (disp_fn_MakeDialog_t *) nodev, (disp_fn_Input_t *) nodev,
gen_DatatoScreen, },
+ { "svg", 0, 0, 1000, 1000, 0, 0,
+ SVG_Init, SVG_NewViewport,
+ SVG_Close, SVG_Clear,
+ SVG_DrawLine, SVG_Arc, SVG_Text,
+ (disp_fn_DefineColor_t*)nodev, (disp_fn_DefineLinestyle_t*)nodev,
+ SVG_SetLinestyle, SVG_SetColor, SVG_Update,
+ (disp_fn_Track_t*)nodev, (disp_fn_MakeMenu_t*)nodev, (disp_fn_MakeDialog_t*)nodev, (disp_fn_Input_t*)nodev,
+ gen_DatatoScreen, },
+
{ "hpgl", 0, 0, 1000, 1000, 0, 0,
GL_Init, GL_NewViewport,
GL_Close, GL_Clear,
diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c
index 77476048b..adbc2fa57 100644
--- a/src/frontend/plotting/grid.c
+++ b/src/frontend/plotting/grid.c
@@ -141,7 +141,7 @@ gr_redrawgrid(GRAPH *graph)
(int)(graph->absolute.width * 0.35),
graph->fontheight, 0);
#else
- if (eq(dispdev->name, "postscript"))
+ if (eq(dispdev->name, "postscript") || eq(dispdev->name, "svg"))
{
DevDrawText(graph->grid.xlabel,
(int)(graph->absolute.width * 0.35),
@@ -232,6 +232,45 @@ gr_redrawgrid(GRAPH *graph)
graph->grid.ylabel) * graph->fontwidth) / 2,
90);
}
+#if !defined(_MSC_VER ) && !defined(__MINGW32__)
+ /* svg for non-Windows */
+ else if (eq(dispdev->name, "svg")) {
+ DevDrawText(graph->grid.ylabel,
+ graph->fontwidth,
+ /* vertical text, midpoint in y is aligned midpoint
+ * of utf-8 text string */
+ graph->absolute.height - (int)(mbstowcs(NULL, graph->grid.ylabel, 0) * graph->fontwidth / 2),
+ 90);
+ }
+#else
+ /* Windows and UTF-8: check for string length (in pixels),
+ place vertical text centered in y with respect to grid */
+ else if (eq(dispdev->name, "svg")) {
+ /* utf-8: figure out the real length of the y label */
+ const int n_byte_wide = 2 * (int)strlen(graph->grid.ylabel) + 1;
+ wchar_t* const wtext = TMALLOC(wchar_t, n_byte_wide);
+ int wlen = MultiByteToWideChar(CP_UTF8, 0, graph->grid.ylabel, -1,
+ wtext, n_byte_wide);
+ if (wlen == 0) {
+ fprintf(stderr, "UTF-8 to wide char conversion failed with 0x%x\n", GetLastError());
+ fprintf(stderr, "%s could not be converted\n", graph->grid.ylabel);
+ }
+ else {
+ SIZE sz;
+ TEXTMETRICW tmw;
+ tpWindowData wd = graph->devdep;
+ GetTextMetricsW(wd->hDC, &tmw);
+ GetTextExtentPoint32W(wd->hDC, wtext, wlen, &sz);
+ // printf("length: %d, deviation: %d\n", sz.cx, sz.cx - graph->fontwidth*wlen);
+ DevDrawText(graph->grid.ylabel,
+ graph->fontwidth,
+ /*vertical text, midpoint in y is aligned midpoint of text string */
+ (graph->absolute.height - (int)(1.2 * sz.cx + tmw.tmOverhang)) / 2, 90);
+ }
+ txfree(wtext);
+ }
+#endif
+
#ifdef EXT_ASC
else if (eq(dispdev->name, "Windows"))
DevDrawText(graph->grid.ylabel,
@@ -288,7 +327,7 @@ gr_redrawgrid(GRAPH *graph)
}
/* draw postscript title */
- if (graph->plotname && eq(dispdev->name, "postscript"))
+ if (graph->plotname && (eq(dispdev->name, "postscript") || eq(dispdev->name, "svg")))
DevDrawText(graph->plotname,
graph->fontwidth,
graph->absolute.height - graph->fontheight, 0);
diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj
index cedc9b4d0..056d32512 100644
--- a/visualc/vngspice.vcxproj
+++ b/visualc/vngspice.vcxproj
@@ -927,6 +927,7 @@
+
@@ -1538,6 +1539,7 @@
+