From d2afa9771789cc4279732a5831278146f638e255 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 13:06:19 +0200 Subject: [PATCH 01/98] Enable utf-8 and UNICODE for string handling. preprocessor flag EXT_ASC resets handling to old behaviour. Add utf-16 wide char to all Windows string i/o. Add translation between utf-8 and utf-16. Add angle to fcn DevDrawText. --- src/frontend/plotting/gnuplot.c | 9 +- src/frontend/plotting/grid.c | 187 ++++++++++++++++---- src/frontend/wdisp/windisp.c | 215 ++++++++++++++++++++--- src/winmain.c | 291 +++++++++++++++++++++++++++++--- 4 files changed, 623 insertions(+), 79 deletions(-) diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index 5a0ff5015..d07c2f310 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -154,9 +154,16 @@ void ft_gnuplot(double *xlims, double *ylims, } /* Set up the file header. */ -#if !defined(__MINGW32__) && !defined(_MSC_VER) +#if !defined(__MINGW__) && !defined(_MSC_VER) && !defined(__CYGWIN__) fprintf(file, "set terminal X11 noenhanced\n"); +#elif defined(__CYGWIN__) +#ifndef EXT_ASC + fprintf(file, "set encoding utf8\n"); +#endif #else +#ifndef EXT_ASC + fprintf(file, "set encoding utf8\n"); +#endif fprintf(file, "set termoption noenhanced\n"); #endif if (title) { diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c index 0c1b2f73b..31d04a51e 100644 --- a/src/frontend/plotting/grid.c +++ b/src/frontend/plotting/grid.c @@ -17,10 +17,31 @@ Modified: 2001 AlansFixes #include +#ifdef HAS_WINGUI +#undef BOOLEAN +#include +typedef struct { /* Extra window data */ + HWND wnd; /* window */ + HDC hDC; /* Device context of window */ + RECT Area; /* plot area */ + int ColorIndex; /* Index of actual color */ + int PaintFlag; /* 1 with WM_PAINT */ + int FirstFlag; /* 1 before first update */ +} tWindowData; +typedef tWindowData *tpWindowData; /* pointer to it */ +#endif + +#ifndef X_DISPLAY_MISSING +extern bool old_x11; +extern int X11_GetLenStr(GRAPH *gr, char* instring); +#endif + #define RAD_TO_DEG (180.0 / M_PI) +#define RELPOSXUNIT 0.6 /* old position of the UNIT label */ typedef enum { x_axis, y_axis } Axis; +static int unitshift; /* shift of unit label if x label is too large */ static double *lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis); static double *loggrid(GRAPH *graph, double lo, double hi, int type, Axis axis); @@ -105,18 +126,6 @@ gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype) graph->datawindow.xmin = dd[0]; graph->datawindow.xmax = dd[1]; - - /* do we really need this? */ - /* - SetLinestyle(0); - DevDrawLine(graph->viewportxoff, graph->viewportyoff, - graph->viewport.width + graph->viewportxoff, - graph->viewportyoff); - DevDrawLine(graph->viewportxoff, graph->viewportyoff, - graph->viewportxoff, - graph->viewport.height + graph->viewportyoff); - SetLinestyle(1); - */ } @@ -128,10 +137,73 @@ gr_redrawgrid(GRAPH *graph) SetLinestyle(1); /* draw labels */ if (graph->grid.xlabel) { +#if defined(EXT_ASC) || (!defined HAS_WINGUI && defined X_DISPLAY_MISSING) DevDrawText(graph->grid.xlabel, - (int) (graph->absolute.width * 0.35), + (int)(graph->absolute.width * 0.35), + graph->fontheight, 0); +#else + if (eq(dispdev->name, "postscript")) + { + DevDrawText(graph->grid.xlabel, + (int)(graph->absolute.width * 0.35), + graph->fontheight, 0); + } + else { +#ifndef X_DISPLAY_MISSING + + /* x axis centered to graphics on X11 */ + /* utf-8: figure out the real length of the x label */ + int wlen = 0, i = 0; + while (graph->grid.xlabel[i]) { + if ((graph->grid.xlabel[i] & 0xc0) != 0x80) + wlen++; + i++; + } + /* string lenth in pixels */ + int strsize = X11_GetLenStr(graph, graph->grid.xlabel); + DevDrawText(graph->grid.xlabel, + (int)((graph->absolute.width - strsize) / 2), graph->fontheight, 0); + /* fix the position of the UNIT label */ + if (RELPOSXUNIT * graph->absolute.width < ((graph->absolute.width + strsize) / 2 + graph->fontwidth)) + unitshift = (int)((graph->absolute.width + strsize) / 2 + - RELPOSXUNIT * graph->absolute.width) + + graph->fontwidth; + else + unitshift = 0; /* reset for next plot window */ + } +#endif +#ifdef HAS_WINGUI + /* x axis centered to graphics on Windows */ + /* utf-8: figure out the real length of the x label */ + wchar_t *wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->grid.xlabel) + 1); + int wlen = MultiByteToWideChar(CP_UTF8, 0, graph->grid.xlabel, -1, wtext, 2 * strlen(graph->grid.xlabel) + 1); + 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.xlabel); + } + else { + SIZE sz; + TEXTMETRICW tmw; + tpWindowData wd = graph->devdep; + GetTextMetricsW(wd->hDC, &tmw); + GetTextExtentPoint32W(wd->hDC, wtext, wlen, &sz); + DevDrawText(graph->grid.xlabel, + (int)((graph->absolute.width - sz.cx + tmw.tmOverhang) / 2), graph->fontheight, 0); + /* fix the position of the UNIT label */ + if (RELPOSXUNIT * graph->absolute.width < (graph->absolute.width + sz.cx + tmw.tmOverhang) / 2 + graph->fontwidth) + unitshift = (int)((graph->absolute.width + sz.cx + tmw.tmOverhang) / 2 + - RELPOSXUNIT * graph->absolute.width) + + graph->fontwidth; + else + unitshift = 0; /* reset for next plot window */ + } + } +#endif +#endif // EXT_ASC } + /* y axis: vertical text, centered to graph */ if (graph->grid.ylabel) { if (graph->grid.gridtype == GRID_POLAR || graph->grid.gridtype == GRID_SMITH || @@ -141,12 +213,57 @@ gr_redrawgrid(GRAPH *graph) graph->fontwidth, (graph->absolute.height * 3) / 4, 0); } else { - if (eq(dispdev->name, "postscript") || eq(dispdev->name, "Windows")) + + if (eq(dispdev->name, "postscript")) + DevDrawText(graph->grid.ylabel, + graph->fontwidth, + /*vertical text, midpoint in y is aligned midpoint of text string */ + (graph->absolute.height - strlen(graph->grid.ylabel) * graph->fontwidth) / 2, 90); +#ifdef EXT_ASC + else if (eq(dispdev->name, "Windows")) DevDrawText(graph->grid.ylabel, graph->fontwidth, /*vertical text, midpoint in y is aligned midpoint of text string */ - (graph->absolute.height - (int) strlen(graph->grid.ylabel) * graph->fontwidth) / 2, 90); - else /* FIXME: for now excluding X11 and others */ + (graph->absolute.height - strlen(graph->grid.ylabel) * graph->fontwidth) / 2, 90); +#else +#ifdef HAS_WINGUI + /* 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, "Windows")) { + /* utf-8: figure out the real length of the y label */ + wchar_t *wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->grid.ylabel) + 1); + int wlen = MultiByteToWideChar(CP_UTF8, 0, graph->grid.ylabel, -1, wtext, 2 * strlen(graph->grid.ylabel) + 1); + 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); + } + } +#endif +#ifndef X_DISPLAY_MISSING + /* new x11 with xft and utf-8 */ + else if (!old_x11) { + /* calculate and add offsets in fcn X11_Text in X11.c */ + DevDrawText(graph->grid.ylabel, + 0, + /*vertical text, y is midpoint of graph height */ + (graph->absolute.height) / 2, 90); + } +#endif +#endif + else /* others */ DevDrawText(graph->grid.ylabel, graph->fontwidth, graph->absolute.height / 2, 90); @@ -324,7 +441,7 @@ lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis) graph->viewportxoff = (digits + 5 + mag - mag3) * graph->fontwidth; /* add height of the vertical text to offset*/ if (graph->grid.ylabel) - graph->viewportxoff += graph->fontheight; + graph->viewportxoff += (int)(1.6 * graph->fontheight); margin = graph->viewportyoff; /*max = graph->viewport.height + graph->viewportyoff;*/ max = graph->absolute.height - graph->viewportyoff; @@ -383,11 +500,10 @@ lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis) buf[0] = '\0'; } - s = ft_typabbrev(type); - if (!s) - s = "Units"; - strncat(buf, s, sizeof(buf) - strlen(buf) - 1); - + if ((s = ft_typabbrev(type)) != NULL) + (void) strncat(buf, s, sizeof(buf) - strlen(buf) - 1); + else + (void) strncat(buf, "Units", sizeof(buf) - strlen(buf) - 1); if (delta == 0.0) { int i; double step; @@ -535,12 +651,12 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double if (axis == x_axis) DevDrawLine(graph->viewportxoff + i, graph->viewportyoff, graph->viewportxoff + i, - graph->viewport.height + graph->viewportyoff); + graph->viewport.height + graph->viewportyoff, TRUE); else DevDrawLine(graph->viewportxoff, graph->viewportyoff + i, graph->viewport.width + graph->viewportxoff, - graph->viewportyoff + i); + graph->viewportyoff + i, TRUE); } if (j == 0) SetLinestyle(1); @@ -562,8 +678,7 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double j += 1000; } if (axis == x_axis) - DevDrawText(units, (int) (graph->absolute.width * 0.6), - graph->fontheight, 0); + DevDrawText(units, (int) (graph->absolute.width * RELPOSXUNIT + unitshift), graph->fontheight, 0); else DevDrawText(units, graph->fontwidth, (int) (graph->absolute.height - 2 * graph->fontheight), 0); @@ -698,13 +813,15 @@ drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, in graph->viewportyoff, graph->viewportxoff + i, graph->viewport.height - +graph->viewportyoff); + +graph->viewportyoff, + TRUE); else DevDrawLine(graph->viewportxoff, graph->viewportyoff + i, graph->viewport.width + graph->viewportxoff, - graph->viewportyoff + i); + graph->viewportyoff + i, + TRUE); } if (j == -2) @@ -745,13 +862,15 @@ drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, in graph->viewportyoff, graph->viewportxoff + m, graph->viewport.height - + graph->viewportyoff); + + graph->viewportyoff, + TRUE); else DevDrawLine(graph->viewportxoff, graph->viewportyoff + m, graph->viewport.width + graph->viewportxoff, - graph->viewportyoff + m); + graph->viewportyoff + m, + TRUE); } } SetLinestyle(0); @@ -759,7 +878,7 @@ drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, in } if (axis == x_axis) - DevDrawText(units, (int) (graph->absolute.width * 0.6), + DevDrawText(units, (int) (graph->absolute.width * RELPOSXUNIT + unitshift), graph->fontheight, 0); else DevDrawText(units, graph->fontwidth, @@ -938,7 +1057,7 @@ drawpolargrid(GRAPH *graph) graph->grid.yaxis.circular.center, graph->grid.xaxis.circular.radius)) { - DevDrawLine(x1, y1, x2, y2); + DevDrawLine(x1, y1, x2, y2, TRUE); /* Add a label here */ /*XXXX*/ adddeglabel(graph, i * 30, x2, y2, x1, y1, @@ -974,7 +1093,7 @@ drawpolargrid(GRAPH *graph) graph->grid.xaxis.circular.center, graph->grid.yaxis.circular.center, graph->grid.xaxis.circular.radius)) { - DevDrawLine(x1, y1, x2, y2); + DevDrawLine(x1, y1, x2, y2, TRUE); /* Put on the label */ adddeglabel(graph, i, x2, y2, x1, y1, graph->grid.xaxis.circular.center, @@ -1313,7 +1432,7 @@ drawsmithgrid(GRAPH *graph) if (zheight < 0) zheight = - zheight; DevDrawLine(gr_xcenter - zheight, gr_ycenter + yoff, - gr_xcenter + zheight, gr_ycenter + yoff); + gr_xcenter + zheight, gr_ycenter + yoff, TRUE); DevDrawText("0", gr_xcenter + zheight + gi_fntwidth, gr_ycenter + yoff - gi_fntheight / 2, 0); DevDrawText("o", gr_xcenter + zheight + gi_fntwidth * 2, gr_ycenter + yoff, 0); diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 598f613e0..293c0e28d 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -3,7 +3,7 @@ * Wolfgang Muees 27.10.97 * Holger Vogt 07.12.01 * Holger Vogt 05.12.07 - * Holger Vogt 01.11.18 + * Holger Vogt 01.11.18 */ #include "ngspice/ngspice.h" @@ -73,6 +73,7 @@ extern void com_hardcopy(wordlist *wl); #endif #define DEF_FONTW "Arial" +#define DEFW_FONTW L"Arial" /* local variables */ static int IsRegistered = 0; /* 1 if window class is registered */ @@ -80,6 +81,8 @@ static int IsRegistered = 0; /* 1 if window class is regis static COLORREF ColorTable[NumWinColors]; /* color memory */ static char *WindowName = "Spice Plot"; /* window name */ static WNDCLASS TheWndClass; /* Plot-window class */ +static wchar_t * WindowNameW = L"Spice Plot"; /* window name */ +static WNDCLASSW TheWndClassW; /* Plot-window class */ static HFONT PlotFont; /* which font */ #define ID_DRUCKEN 0xEFF0 /* System Menue: print */ #define ID_DRUCKEINR 0xEFE0 /* System Menue: printer setup */ @@ -91,9 +94,14 @@ static char *STR_DRUCKEN = "Printer..."; /* System menue strings */ static char *STR_DRUCKEINR = "Printer setup..."; static char *STR_HARDCOPY = "Postscript file, color"; static char *STR_HARDCOPY_BW = "Postscript file, b&w"; +static wchar_t * STRW_DRUCKEN = L"Printer..."; /* System menue strings */ +static wchar_t * STRW_DRUCKEINR = L"Printer setup..."; +static wchar_t * STRW_HARDCOPY = L"Postscript file, color"; +static wchar_t * STRW_HARDCOPY_BW = L"Postscript file, b&w"; static bool isblack = TRUE; /* background color of plot is black */ static bool isblackold = TRUE; static int linewidth = 0; /* linewidth of grid and plot */ +static int gridlinewidth = 0; /* linewidth of grid */ /****************************************************************************** WIN_Init() makes connection to graphics. We have to determine @@ -110,6 +118,13 @@ WIN_Init() does not yet open a window, this happens only in WIN_NewViewport() int WIN_Init(void) { char colorstring[BSIZE_SP]; + char facename[32]; + +#ifdef EXT_ASC + LOGFONT lf; +#else + LOGFONTW lfw; +#endif /* Initialization of display descriptor */ dispdev->width = GetSystemMetrics(SM_CXSCREEN); @@ -120,8 +135,10 @@ int WIN_Init(void) /* always, user may have set color0 to white */ /* get background color information from spinit, only "white" is recognized as a suitable option! */ - if (cp_getvar("color0", CP_STRING, colorstring, sizeof(colorstring))) - isblack = !cieq(colorstring, "white"); + if (cp_getvar("color0", CP_STRING, colorstring, sizeof(colorstring))) { + if (cieq(colorstring, "white")) isblack = FALSE; + else isblack = TRUE; + } /* get linewidth information from spinit */ if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) { @@ -131,18 +148,17 @@ int WIN_Init(void) linewidth = 0; } + /* get linewidth for grid from spinit */ + if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = linewidth; + if (gridlinewidth < 0) + gridlinewidth = 0; + /* only for the first time: */ if (!IsRegistered) { isblackold = isblack; - /* get linewidth information from spinit - * if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) - * linewidth = 0; - * if (linewidth < 0) - * linewidth = 0; - */ - /* Initialize colors */ if (isblack) { ColorTable[0] = RGB( 0, 0, 0); /* black = background */ @@ -184,8 +200,8 @@ int WIN_Init(void) ColorTable[22] = RGB(255, 128, 128); /* pink */ /* Ansii fixed font */ - PlotFont = GetStockFont(ANSI_FIXED_FONT); - +// PlotFont = GetStockFont(ANSI_FIXED_FONT); +#ifdef EXT_ASC /* register window class */ TheWndClass.lpszClassName = WindowName; TheWndClass.hInstance = hInst; @@ -207,7 +223,25 @@ int WIN_Init(void) if (!RegisterClass(&TheWndClass)) { return 1; - } + +#else + /* register window class */ + TheWndClassW.lpszClassName = WindowNameW; + TheWndClassW.hInstance = hInst; + TheWndClassW.lpfnWndProc = PlotWindowProc; + TheWndClassW.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + TheWndClassW.lpszMenuName = NULL; + TheWndClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512) /*IDC_ARROW*/); + if (isblack) + TheWndClassW.hbrBackground = GetStockObject(BLACK_BRUSH); + else + TheWndClassW.hbrBackground = GetStockObject(WHITE_BRUSH); + TheWndClassW.hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(2)); + TheWndClassW.cbClsExtra = 0; + TheWndClassW.cbWndExtra = sizeof(GRAPH *); + if (!RegisterClassW(&TheWndClassW)) return 1; +#endif + } /* not first time */ else if (isblackold != isblack) { @@ -229,6 +263,55 @@ int WIN_Init(void) isblackold = isblack; } IsRegistered = 1; +#ifdef EXT_ASC + // lf.lfHeight = 18; + lf.lfWidth = 0; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfWeight = 500; + lf.lfItalic = 0; + lf.lfUnderline = 0; + lf.lfStrikeOut = 0; + lf.lfCharSet = 0; + lf.lfOutPrecision = 0; + lf.lfClipPrecision = 0; + lf.lfQuality = 0; + lf.lfPitchAndFamily = 0; + /* set up fonts */ + if (!cp_getvar("wfont", CP_STRING, lf.lfFaceName)) { + (void)lstrcpy(lf.lfFaceName, DEF_FONTW); + } + if (!cp_getvar("wfont_size", CP_NUM, &(lf.lfHeight))) { + lf.lfHeight = 18; + } + PlotFont = CreateFontIndirect(&lf); +#else + // lfw.lfHeight = 18; + lfw.lfWidth = 0; + lfw.lfEscapement = 0; + lfw.lfOrientation = 0; + lfw.lfWeight = 500; + lfw.lfItalic = 0; + lfw.lfUnderline = 0; + lfw.lfStrikeOut = 0; + lfw.lfCharSet = 0; + lfw.lfOutPrecision = 0; + lfw.lfClipPrecision = 0; + lfw.lfQuality = 0; + lfw.lfPitchAndFamily = 0; + if (!cp_getvar("wfont", CP_STRING, facename, sizeof(facename))) { + (void)lstrcpyW(lfw.lfFaceName, DEFW_FONTW); + } + else { + wchar_t wface[32]; + swprintf(wface, 32, L"%S", facename); + (void)lstrcpyW(lfw.lfFaceName, wface); + } + if (!cp_getvar("wfont_size", CP_NUM, &(lfw.lfHeight), 0)) { + lfw.lfHeight = 18; + } + PlotFont = CreateFontIndirectW(&lfw); +#endif /* ready */ return 0; @@ -239,7 +322,11 @@ int WIN_Init(void) /* (attach to window) */ static GRAPH *pGraph(HWND hwnd) { +#ifdef EXT_ASC return (GRAPH *) GetWindowLongPtr(hwnd, 0); +#else + return (GRAPH *) GetWindowLongPtrW( hwnd, 0); +#endif } @@ -599,7 +686,11 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, default: WIN_DEFAULT: +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); +#else + return DefWindowProcW( hwnd, uMsg, wParam, lParam); +#endif } } @@ -616,7 +707,11 @@ int WIN_NewViewport(GRAPH *graph) int i; HWND window; HDC dc; +#ifdef EXT_ASC TEXTMETRIC tm; +#else + TEXTMETRICW tmw; +#endif tpWindowData wd; HMENU sysmenu; @@ -642,9 +737,23 @@ int WIN_NewViewport(GRAPH *graph) /* Create the window */ i = GetSystemMetrics(SM_CYSCREEN) / 3; +#ifdef EXT_ASC window = CreateWindow(WindowName, graph->plotname, WS_OVERLAPPEDWINDOW, 0, 0, WinLineWidth, i * 2 - 22, NULL, NULL, hInst, NULL); - if (!window) { +#else + /* UTF-8 support */ + wchar_t *wtext, *wtext2; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->plotname) + 1); + wtext2 = TMALLOC(wchar_t, 2 * strlen(WindowName) + 1); + /* translate UTF-8 to UTF-16 */ + MultiByteToWideChar(CP_UTF8, 0, graph->plotname, -1, wtext, 2 * strlen(graph->plotname) + 1); + MultiByteToWideChar(CP_UTF8, 0, WindowName, -1, wtext2, 2 * strlen(WindowName) + 1); + window = CreateWindowW(wtext2, wtext, WS_OVERLAPPEDWINDOW, + 0, 0, WinLineWidth, i * 2 - 22, NULL, NULL, hInst, NULL); + tfree(wtext); + tfree(wtext2); +#endif + if (!window) return 1; } @@ -695,11 +804,17 @@ int WIN_NewViewport(GRAPH *graph) SelectObject(dc, PlotFont); /* query the font parameters */ +#ifdef EXT_ASC if (GetTextMetrics(dc, &tm)) { graph->fontheight = tm.tmHeight; graph->fontwidth = tm.tmAveCharWidth; } - +#else + if (GetTextMetricsW(dc, &tmw)) { + graph->fontheight = tmw.tmHeight; + graph->fontwidth = tmw.tmAveCharWidth + 1; /*FIXME relationship between height and width for various fonts*/ + } +#endif /* set viewport parameters */ graph->viewport.height = wd->Area.bottom; graph->viewport.width = wd->Area.right; @@ -767,7 +882,8 @@ int WIN_Clear(void) } -int WIN_DrawLine(int x1, int y1, int x2, int y2) +int +WIN_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { tpWindowData wd; HPEN OldPen; @@ -781,7 +897,10 @@ int WIN_DrawLine(int x1, int y1, int x2, int y2) return 0; MoveToEx(wd->hDC, x1, wd->Area.bottom - y1, NULL); - NewPen = CreatePen(LType(wd->ColorIndex), linewidth, ColorTable[wd->ColorIndex]); + if (isgrid) + NewPen = CreatePen(LType(wd->ColorIndex), gridlinewidth, ColorTable[wd->ColorIndex]); + else + NewPen = CreatePen(LType(wd->ColorIndex), linewidth, ColorTable[wd->ColorIndex]); OldPen = SelectObject(wd->hDC, NewPen); LineTo(wd->hDC, x2, wd->Area.bottom - y2); OldPen = SelectObject(wd->hDC, OldPen); @@ -875,7 +994,13 @@ int WIN_Text(char *text, int x, int y, int angle) { tpWindowData wd; HFONT hfont; +#ifdef EXT_ASC LOGFONT lf; +#else + LOGFONTW lfw; +#endif + + if (!currentgraph) return 0; @@ -884,6 +1009,7 @@ int WIN_Text(char *text, int x, int y, int angle) if (!wd) return 0; +#ifdef EXT_ASC lf.lfHeight = (int) (1.1 * currentgraph->fontheight); lf.lfWidth = 0; lf.lfEscapement = angle * 10; @@ -903,15 +1029,60 @@ int WIN_Text(char *text, int x, int y, int angle) (void) lstrcpy(lf.lfFaceName, DEF_FONTW); if (!cp_getvar("wfont_size", CP_NUM, &(lf.lfHeight), 0)) - lf.lfHeight = (int) (1.3 * currentgraph->fontheight); + lf.lfHeight = 18; + //lf.lfHeight = (int) (1.3 * currentgraph->fontheight); + + hfont = CreateFontIndirect (&lf); +#else + char facename[32]; + lfw.lfHeight = (int)(1.1 * currentgraph->fontheight); + lfw.lfWidth = 0; + lfw.lfEscapement = angle * 10; + lfw.lfOrientation = angle * 10; + lfw.lfWeight = 500; + lfw.lfItalic = 0; + lfw.lfUnderline = 0; + lfw.lfStrikeOut = 0; + lfw.lfCharSet = 0; + lfw.lfOutPrecision = 0; + lfw.lfClipPrecision = 0; + lfw.lfQuality = 0; + lfw.lfPitchAndFamily = 0; + + /* set up fonts */ + if (!cp_getvar("wfont", CP_STRING, facename, sizeof(facename))) { + (void)lstrcpyW(lfw.lfFaceName, DEFW_FONTW); + } + else { + wchar_t wface[32]; + swprintf(wface, 32, L"%S", facename); + (void)lstrcpyW(lfw.lfFaceName, wface); + } + if (!cp_getvar("wfont_size", CP_NUM, &(lfw.lfHeight), 0)) { + lfw.lfHeight = 18; + } + else { + currentgraph->fontheight = lfw.lfHeight; + currentgraph->fontwidth = (int)(lfw.lfHeight*0.52); + } + + hfont = CreateFontIndirectW(&lfw); +#endif SelectObject(wd->hDC, hfont); SetTextColor(wd->hDC, ColorTable[wd->ColorIndex]); +#ifdef EXT_ASC TextOut(wd->hDC, x, wd->Area.bottom - y - currentgraph->fontheight, text, (int)strlen(text)); - - DeleteObject(SelectObject(wd->hDC, GetStockObject(SYSTEM_FONT))); +#else + wchar_t *wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(text) + 1); + MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, 2 * strlen(text) + 1); + TextOutW(wd->hDC, x, wd->Area.bottom - y - currentgraph->fontheight, wtext, 2 * (int)strlen(text) + 1); + tfree(wtext); +#endif + DeleteObject(SelectObject(wd->hDC, hfont)); return 0; } @@ -1018,8 +1189,8 @@ static void WIN_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy) { lmin = log10(graph->datawindow.ymin); lmax = log10(graph->datawindow.ymax); - *fy = exp(((graph->absolute.height - y - graph->viewportyoff) * - (lmax - lmin) / graph->viewport.height + lmin) * M_LN10); + *fy = exp(((graph->absolute.height - y - graph->viewportxoff) * + (lmax - lmin) / graph->viewport.height + lmin) * M_LN10); } else { *fy = ((graph->absolute.height - y) - graph->viewportyoff) * graph->aspectratioy + graph->datawindow.ymin; diff --git a/src/winmain.c b/src/winmain.c index c1498dee7..aef846540 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -2,6 +2,7 @@ Autor: Wolfgang Muees Stand: 28.10.97 Copyright: Holger Vogt + Stand: 09.01.2018 Stand: 20.07.2019 Modified BSD license */ @@ -30,6 +31,7 @@ #include "hist_info.h" /* history management */ #include "ngspice/bool.h" /* bool defined as unsigned char */ #include "misc/misc_time.h" /* timediff */ +#include "ngspice/memory.h" /* TMALLOC */ #include "winmain.h" /* Constants */ @@ -76,28 +78,42 @@ HWND hwQuitButton; /* Pause button */ static int nReturnCode = 0; /* WinMain return value */ static int nShowState; /* Display mode of main window */ static WNDCLASS hwMainClass; /* Class definition for the main window */ +static WNDCLASSW hwMainClassW; /* Class definition for the main window */ static LPCTSTR hwClassName = "SPICE_TEXT_WND";/* Class name of the main window */ static LPCTSTR hwWindowName = PACKAGE_STRING; /* main window displayed name */ +static LPCWSTR hwClassNameW = L"SPICE_TEXT_WND";/* Class name of the main window */ +static LPCWSTR hwWindowNameW = L"ngspice 26"; /* main window displayed name */ static WNDCLASS twTextClass; /* Class definition for the text box */ +static WNDCLASSW twTextClassW; /* Class definition for the text box */ static LPCTSTR twClassName = "SPICE_TEXT_BOX"; /* Class name for the text box */ static LPCTSTR twWindowName = "TextOut"; /* text box name */ +static LPCWSTR twClassNameW = L"SPICE_TEXT_BOX"; /* Class name for the text box */ +static LPCWSTR twWindowNameW = L"TextOut"; /* text box name */ static size_t TBufEnd = 0; /* Pointer to \0 */ static char TBuffer[TBufSize + 1]; /* Text buffer */ static SBufLine SBuffer; /* Input buffer */ static WNDCLASS swStringClass; /* Class definition of string window */ static LPCTSTR swClassName = "SPICE_STR_IN"; /* Class name of text input */ static LPCTSTR swWindowName = "StringIn"; /* Window name */ +static WNDCLASSW swStringClassW; /* Class definition of string window */ +static LPCWSTR swClassNameW = L"SPICE_STR_IN"; /* Class name of text input */ +static LPCWSTR swWindowNameW = L"StringIn"; /* Window name */ static char CRLF[] = {CR, LF, SE}; /* CR/LF */ static WNDCLASS hwElementClass; /* Class definition of status displays */ static LPCTSTR hwElementClassName = "ElementClass"; static LPCTSTR hwSourceWindowName = "SourceDisplay"; static LPCTSTR hwAnalyseWindowName = "AnalyseDisplay"; +static WNDCLASSW hwElementClassW; /* Class definition of status displays */ +static LPCWSTR hwElementClassNameW = L"ElementClass"; +static LPCWSTR hwSourceWindowNameW = L"SourceDisplay"; +static LPCWSTR hwAnalyseWindowNameW = L"AnalyseDisplay"; static int RowHeight = 16; /* Height of line of text */ static int LineHeight = 25; /* Height of input line */ static int VisibleRows = 10; /* Number of visible lines in text window */ static BOOL DoUpdate = FALSE; /* Update text window */ static WNDPROC swProc = NULL; /* original string window procedure */ static WNDPROC twProc = NULL; /* original text window procedure */ +static HFONT sfont; /* Font for source and analysis window */ extern bool ft_ngdebug; /* some additional debug info printed */ extern bool ft_batchmode; @@ -160,9 +176,17 @@ void SetSource(char *Name) { if (hwSource) { +#ifdef EXT_ASC SetWindowText(hwSource, Name); +#else + wchar_t *NameW; + NameW = TMALLOC(wchar_t, 2 * strlen(Name) + 1); + MultiByteToWideChar(CP_UTF8, 0, Name, -1, NameW, 2 * strlen(Name) + 1); + SetWindowTextW(hwSource, NameW); + tfree(NameW); +#endif InvalidateRgn(hwSource, NULL, TRUE); - } + } } @@ -203,9 +227,9 @@ SetAnalyse(char *Analyse, /* in: analysis type */ OldPercent = DecaPercent; /* output only into hwAnalyse window and if time elapsed is larger than DELTATIME given value, or if analysis has changed, else return */ - if (((diffsec > 0) || (diffmillisec > DELTATIME) || strcmp(OldAn, Analyse))) { + if (hwAnalyse && ((diffsec > 0) || (diffmillisec > DELTATIME) || strcmp(OldAn, Analyse))) { if (DecaPercent < 0) { - sprintf(s, "--ready--"); + sprintf(s, " -- ready --"); sprintf(t, "%s", PACKAGE_STRING); } else if (DecaPercent == 0) { @@ -231,8 +255,17 @@ SetAnalyse(char *Analyse, /* in: analysis type */ strncpy(OldAn, Analyse, 127); } +#ifdef EXT_ASC SetWindowText(hwAnalyse, s); SetWindowText(hwMain, t); +#else + wchar_t sw[256]; + wchar_t tw[256]; + swprintf(sw, 256, L"%S", s); + swprintf(tw, 256, L"%S", t); + SetWindowTextW(hwAnalyse, sw); + SetWindowTextW(hwMain, tw); +#endif InvalidateRgn(hwAnalyse, NULL, TRUE); InvalidateRgn(hwMain, NULL, TRUE); } @@ -359,8 +392,17 @@ AppendString(const char *Line) static void DisplayText(void) { - // Darstellen + // Show text +#ifdef EXT_ASC Edit_SetText(twText, TBuffer); +#else + wchar_t *TWBuffer; + TWBuffer = TMALLOC(wchar_t, 2 * strlen(TBuffer) + 1); + if (MultiByteToWideChar(CP_UTF8, 0, TBuffer, -1, TWBuffer, 2 * strlen(TBuffer) + 1) == 0) + swprintf(TWBuffer, 2 * strlen(TBuffer), L"UTF-8 to UTF-16 conversion failed with 0x%x\n%hs could not be converted\n", GetLastError(), TBuffer); + SetWindowTextW(twText, TWBuffer); + tfree(TWBuffer); +#endif // Scroller updaten, neuen Text darstellen AdjustScroller(); } @@ -454,14 +496,12 @@ Main_OnSize(HWND hwnd, UINT state, int cx, int cy) MoveWindow(swString, 0, h, cx, LineHeight, TRUE); /* Expand Status Elements */ - h = cy - LineHeight + StatusFrame - 1; - MoveWindow(hwSource, StatusFrame, h, SourceLength, StatusElHeight, TRUE); - MoveWindow(hwAnalyse, - cx - 3 * StatusFrame - QuitButtonLength - AnalyseLength - 20, - h, AnalyseLength, StatusElHeight, TRUE); - MoveWindow(hwQuitButton, - cx - StatusFrame - QuitButtonLength - 20, - h, QuitButtonLength, StatusElHeight, TRUE); + h = cy - LineHeight + StatusFrame - 2; + int statbegin = 3 * StatusFrame + QuitButtonLength + AnalyseLength + 4; + MoveWindow(hwSource, StatusFrame, h, cx - statbegin - BorderSize, StatusElHeight, TRUE); + MoveWindow( hwAnalyse, cx - statbegin, h, AnalyseLength, StatusElHeight, TRUE); + MoveWindow( hwQuitButton, cx - StatusFrame - QuitButtonLength - 1, + h + 1, QuitButtonLength, StatusElHeight, TRUE); } @@ -504,7 +544,11 @@ MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) default: DEFAULT_AFTER: +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); +#else + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +#endif } } @@ -592,7 +636,11 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } /* end of switch over handled messages */ /* Fowrard to be processed further by swProc */ - return CallWindowProc(swProc, hwnd, uMsg, wParam, lParam); +#ifdef EXT_ASC + return CallWindowProc(swProc, hwnd, uMsg, wParam, lParam); +#else + return CallWindowProcW( swProc, hwnd, uMsg, wParam, lParam); +#endif } @@ -628,7 +676,11 @@ TextWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } default: DEFAULT_TEXT: +#ifdef EXT_ASC return CallWindowProc(twProc, hwnd, uMsg, wParam, lParam); +#else + return CallWindowProcW( twProc, hwnd, uMsg, wParam, lParam); +#endif } } @@ -640,7 +692,11 @@ Element_OnPaint(HWND hwnd) RECT r; RECT s; HGDIOBJ o; +#ifdef EXT_ASC char buffer[128]; +#else + wchar_t bufferW[256]; +#endif int i; /* Prepare */ @@ -669,6 +725,7 @@ Element_OnPaint(HWND hwnd) FillRect(hdc, &s, o); /* Draw contents */ +#ifdef EXT_ASC buffer[0] = '\0'; i = GetWindowText(hwnd, buffer, 127); s.left = r.left + 1; @@ -679,7 +736,19 @@ Element_OnPaint(HWND hwnd) FillRect(hdc, &s, o); SetBkMode(hdc, TRANSPARENT); ExtTextOut(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, buffer, (unsigned)i, NULL); - +#else + bufferW[0] = '\0'; + i = GetWindowTextW(hwnd, bufferW, 255); + s.left = r.left + 1; + s.right = r.right - 1; + s.top = r.top + 1; + s.bottom = r.bottom - 1; + o = GetSysColorBrush(COLOR_BTNFACE); + FillRect(hdc, &s, o); + SetBkMode(hdc, TRANSPARENT); + SelectObject(hdc, sfont); + ExtTextOutW(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, bufferW, (unsigned)i, NULL); +#endif /* End */ EndPaint(hwnd, &ps); } @@ -696,7 +765,11 @@ ElementWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; default: +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); +#else + return DefWindowProcW( hwnd, uMsg, wParam, lParam); +#endif } } @@ -850,9 +923,16 @@ MakeArgcArgv(char *cmdline, int *argc, char ***argv) /* Main entry point for our Windows application */ +#ifdef EXT_ASC int WINAPI -WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, - _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) +WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) +#elif __MINGW32__ /* MINGW bug not knowing wWinMain */ +int WINAPI +WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR nolpszCmdLine, _In_ int nCmdShow) +#else +int WINAPI +wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR wlpszCmdLine, _In_ int nCmdShow) +#endif { int ix, iy; /* width and height of screen */ int status; @@ -871,6 +951,38 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, NG_IGNORE(hPrevInstance); +#ifndef EXT_ASC + /* convert wchar to utf-8 */ + + /* MINGW not knowing wWinMain + https://github.com/coderforlife/mingw-unicode-main/blob/master/mingw-unicode-gui.c + */ +#ifdef __MINGW32__ + NG_IGNORE(nolpszCmdLine); + char lpszCmdLine[1024]; + wchar_t *lpCmdLine = GetCommandLineW(); + if (__argc == 1) { // avoids GetCommandLineW bug that does not always quote the program name if no arguments + do { ++lpCmdLine; } while (*lpCmdLine); + } + else { + BOOL quoted = lpCmdLine[0] == L'"'; + ++lpCmdLine; // skips the " or the first letter (all paths are at least 1 letter) + while (*lpCmdLine) { + if (quoted && lpCmdLine[0] == L'"') { quoted = FALSE; } // found end quote + else if (!quoted && lpCmdLine[0] == L' ') { + // found an unquoted space, now skip all spaces + do { ++lpCmdLine; } while (lpCmdLine[0] == L' '); + break; + } + ++lpCmdLine; + } + } + WideCharToMultiByte(CP_UTF8, 0, lpCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); +#else + char lpszCmdLine[1024]; + WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); +#endif +#endif /* fill global variables */ hInst = hInstance; nShowState = nCmdShow; @@ -881,6 +993,7 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, SBuffer[0] = SE; /* Define main window class */ +#ifdef EXT_ASC hwMainClass.style = CS_HREDRAW | CS_VREDRAW; hwMainClass.lpfnWndProc = MainWindowProc; hwMainClass.cbClsExtra = 0; @@ -894,8 +1007,23 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&hwMainClass)) goto THE_END; +#else + hwMainClassW.style = CS_HREDRAW | CS_VREDRAW; + hwMainClassW.lpfnWndProc = MainWindowProc; + hwMainClassW.cbClsExtra = 0; + hwMainClassW.cbWndExtra = 0; + hwMainClassW.hInstance = hInst; + hwMainClassW.hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(1)); + hwMainClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512)); + hwMainClassW.hbrBackground = GetStockObject(LTGRAY_BRUSH); + hwMainClassW.lpszMenuName = NULL; + hwMainClassW.lpszClassName = hwClassNameW; + if (!RegisterClassW(&hwMainClassW)) + goto THE_END; +#endif /* Define text window class */ +#ifdef EXT_ASC if (!GetClassInfo(NULL, "EDIT", &twTextClass)) goto THE_END; @@ -907,8 +1035,19 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&twTextClass)) goto THE_END; +#else + if (!GetClassInfoW(NULL, L"EDIT", &twTextClassW)) goto THE_END; + twProc = twTextClassW.lpfnWndProc; + twTextClassW.lpfnWndProc = TextWindowProc; + twTextClassW.hInstance = hInst; + twTextClassW.lpszMenuName = NULL; + twTextClassW.lpszClassName = twClassNameW; + if (!RegisterClassW(&twTextClassW)) + goto THE_END; +#endif /* Define string window class */ +#ifdef EXT_ASC if (!GetClassInfo(NULL, "EDIT", &swStringClass)) goto THE_END; @@ -920,8 +1059,19 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&swStringClass)) goto THE_END; +#else + if (!GetClassInfoW(NULL, L"EDIT", &swStringClassW)) goto THE_END; + swProc = swStringClassW.lpfnWndProc; + swStringClassW.lpfnWndProc = StringWindowProc; + swStringClassW.hInstance = hInst; + swStringClassW.lpszMenuName = NULL; + swStringClassW.lpszClassName = swClassNameW; + if (!RegisterClassW(&swStringClassW)) + goto THE_END; +#endif /* Define status element class */ +#ifdef EXT_ASC hwElementClass.style = CS_HREDRAW | CS_VREDRAW; hwElementClass.lpfnWndProc = ElementWindowProc; hwElementClass.cbClsExtra = 0; @@ -935,34 +1085,67 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&hwElementClass)) goto THE_END; +#else + hwElementClassW.style = CS_HREDRAW | CS_VREDRAW; + hwElementClassW.lpfnWndProc = ElementWindowProc; + hwElementClassW.cbClsExtra = 0; + hwElementClassW.cbWndExtra = 0; + hwElementClassW.hInstance = hInst; + hwElementClassW.hIcon = NULL; + hwElementClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512)); + hwElementClassW.hbrBackground = GetStockObject(LTGRAY_BRUSH); + hwElementClassW.lpszMenuName = NULL; + hwElementClassW.lpszClassName = hwElementClassNameW; + if (!RegisterClassW(&hwElementClassW)) + goto THE_END; +#endif - /*Create main window */ -// iy = GetSystemMetrics(SM_CYSCREEN); -// iyt = GetSystemMetrics(SM_CYSCREEN) / 3; -// ix = GetSystemMetrics(SM_CXSCREEN); + /* Font for element status windows (source, analysis) */ + sfont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, L""); +// sfont = CreateFontW(15, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); /*Create main window */ +#ifdef EXT_ASC SystemParametersInfo(SPI_GETWORKAREA, 0, &wsize, 0); +#else + SystemParametersInfoW(SPI_GETWORKAREA, 0, &wsize, 0); +#endif iy = wsize.bottom; ix = wsize.right; #ifndef BIG_WINDOW_FOR_DEBUGGING const int iyt = iy / 3; /* height of screen divided by 3 */ +#ifdef EXT_ASC hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, - 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); #else + hwMain = CreateWindowW(hwClassNameW, hwWindowNameW, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); +#endif +#else +#ifdef EXT_ASC hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 0, 0, ix, iy, NULL, NULL, hInst, NULL); +#else + hwMain = CreateWindowW(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + 0, 0, ix, iy, NULL, NULL, hInst, NULL); +#endif #endif if (!hwMain) goto THE_END; /* Create text window */ +#ifdef EXT_ASC twText = CreateWindowEx(WS_EX_NOPARENTNOTIFY, twClassName, twWindowName, ES_LEFT | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_BORDER | WS_VSCROLL, 20, 20, 300, 100, hwMain, NULL, hInst, NULL); +#else + twText = CreateWindowExW(WS_EX_NOPARENTNOTIFY, twClassNameW, twWindowNameW, + ES_LEFT | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_BORDER | WS_VSCROLL, + 20,20,300,100, hwMain, NULL, hInst, NULL); +#endif if (!twText) goto THE_END; /* Ansii fixed font */ +#ifdef EXT_ASC { HDC textDC; HFONT font; @@ -979,9 +1162,32 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, ReleaseDC(twText, textDC); } } +#else + { + HDC textDC; + HFONT font; + TEXTMETRICW tm; +// font = CreateFontW(14, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Lucida Console"); +// if(!font) + font = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); + if(!font) + font = GetStockFont(ANSI_FIXED_FONT); + SetWindowFont( twText, font, FALSE); + textDC = GetDC( twText); + if (textDC) { + SelectObject( textDC, font); + if (GetTextMetricsW( textDC, &tm)) { + RowHeight = tm.tmHeight; + WinLineWidth = 90 * tm.tmAveCharWidth; + } + ReleaseDC( twText, textDC); + } + } +#endif /* Create string window for input. Give a handle to history info to * the window for saving and retrieving commands */ +#ifdef EXT_ASC swString = CreateWindowEx(WS_EX_NOPARENTNOTIFY, swClassName, swWindowName, ES_LEFT | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, /* Allow text to scroll */ @@ -999,29 +1205,70 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize; ReleaseDC(swString, stringDC); } - } + } +#else + swString = CreateWindowExW(WS_EX_NOPARENTNOTIFY, swClassNameW, swWindowNameW, + ES_LEFT | WS_CHILD | WS_BORDER, 20, 20, 300, 100, hwMain, NULL, hInst, NULL); + if (!swString) + goto THE_END; + { + HDC stringDC; + TEXTMETRIC tm; + stringDC = GetDC(swString); + if (stringDC) { + if (GetTextMetricsW(stringDC, &tm)) + LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize; + ReleaseDC(swString, stringDC); + } + } +#endif + + + /* Create source window */ +#ifdef EXT_ASC hwSource = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwSourceWindowName, WS_CHILD, 0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL); if (!hwSource) goto THE_END; +#else + hwSource = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwSourceWindowNameW, + WS_CHILD, + 0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL); + if (!hwSource) goto THE_END; +#endif /* Create analysis window */ +#ifdef EXT_ASC hwAnalyse = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwAnalyseWindowName, WS_CHILD, 0, 0, AnalyseLength, StatusElHeight, hwMain, NULL, hInst, NULL); +#else + hwAnalyse = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwAnalyseWindowNameW, + WS_CHILD, + 0,0, AnalyseLength, StatusElHeight, hwMain, NULL, hInst, NULL); +#endif if (!hwAnalyse) goto THE_END; /* Create "Quit" button */ +#ifdef EXT_ASC hwQuitButton = CreateWindow("BUTTON", "Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength, StatusElHeight, hwMain, (HMENU)(UINT_PTR)QUIT_BUTTON_ID, hInst, NULL); +#else + hwQuitButton = CreateWindowW(L"BUTTON", L"Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength, + StatusElHeight, hwMain, (HMENU)(UINT_PTR)QUIT_BUTTON_ID, hInst, NULL); +#endif if (!hwQuitButton) goto THE_END; + /* Define a minimum width */ + int MinWidth = AnalyseLength + SourceLength + QuitButtonLength + 48; + if (WinLineWidth < MinWidth) + WinLineWidth = MinWidth; /* Make main window and subwindows visible. Size of windows allows display of 80 character line. From a4cf5eae443a07c59ed6f709786e43459d92360c Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 16 Feb 2020 09:53:30 +0100 Subject: [PATCH 02/98] remove bracket left over from recent manual merge conflict resolution --- src/frontend/wdisp/windisp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 293c0e28d..6f7f99d9b 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -755,8 +755,6 @@ int WIN_NewViewport(GRAPH *graph) #endif if (!window) return 1; - } - /* change the background color of all windows (both new and already plotted) by assessing the registered window class */ From 904cc4a1bcaf4b48ec3ae00ef577a6c0f0c62a7f Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Dec 2019 15:15:00 +0100 Subject: [PATCH 03/98] add extended ascii and its selection converter UTF-8 to ISO-8859-1/ISO-8859-15 --- src/frontend/postsc.c | 144 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 2 deletions(-) diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index a3145b027..966c35e75 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -76,6 +76,7 @@ static int hcopygraphid; void PS_LinestyleColor(int linestyleid, int colorid); void PS_SelectColor(int colorid); void PS_Stroke(void); +size_t utf8_to_latin9(char *const output, const char *const input, const size_t length); /* Set scale, color and size of the plot */ @@ -170,6 +171,7 @@ int PS_NewViewport(GRAPH *graph) { int x1, x2, y1, y2; hcopygraphid = graph->graphid; + /* devdep initially contains name of output file */ if ((plotfile = fopen((char*)graph->devdep, "w")) == NULL) { perror((char *) graph->devdep); @@ -221,7 +223,6 @@ int PS_NewViewport(GRAPH *graph) fprintf(plotfile, " definefont\n"); fprintf(plotfile, "} def\n"); fprintf(plotfile, "/%s /%sLatin1 ISOLatin1Encoding Re-encode\n", psfont, psfont); - fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale); if (colorflag == 1) { /* set the background to color given in spinit (or 0) */ @@ -233,10 +234,10 @@ int PS_NewViewport(GRAPH *graph) fprintf(plotfile, "closepath fill\n"); } + /* set up a reasonable font */ fprintf(plotfile, "/%sLatin1 findfont %d scalefont setfont\n\n", psfont, (int) (fontsize * scale)); - graph->devdep = TMALLOC(PSdevdep, 1); graph->n_byte_devdep = sizeof(PSdevdep); DEVDEP(graph).lastlinestyle = -1; @@ -331,6 +332,9 @@ int PS_Text(char *text, int x, int y, int angle) { int savedlstyle, savedcolor; +#ifndef EXT_ASC + utf8_to_latin9(text, text, strlen(text)); +#endif /* set linestyle to solid or may get funny color text on some plotters */ savedlstyle = currentgraph->linestyle; @@ -523,3 +527,139 @@ void PS_Stroke(void) DEVDEP(currentgraph).linecount = 0; } } + +/* UTF-8 to ISO-8859-1/ISO-8859-15 mapper. +* Return 0..255 for valid ISO-8859-15 code points, 256 otherwise. +*/ +static inline unsigned int to_latin9(const unsigned int code) +{ + /* Code points 0 to U+00FF are the same in both. */ + if (code < 256U) + return code; + switch (code) { + case 0x0152U: return 188U; /* U+0152 = 0xBC: OE ligature */ + case 0x0153U: return 189U; /* U+0153 = 0xBD: oe ligature */ + case 0x0160U: return 166U; /* U+0160 = 0xA6: S with caron */ + case 0x0161U: return 168U; /* U+0161 = 0xA8: s with caron */ + case 0x0178U: return 190U; /* U+0178 = 0xBE: Y with diaresis */ + case 0x017DU: return 180U; /* U+017D = 0xB4: Z with caron */ + case 0x017EU: return 184U; /* U+017E = 0xB8: z with caron */ + case 0x20ACU: return 164U; /* U+20AC = 0xA4: Euro */ + default: return 256U; + } +} + +/* Convert an UTF-8 string to ISO-8859-15. +* All invalid sequences are ignored. +* Note: output == input is allowed, +* but input < output < input + length +* is not. +* Output has to have room for (length+1) chars, including the trailing NUL byte. +from http://stackoverflow.com/questions/11156473/is-there-a-way-to-convert-from-utf8-to-iso-8859-1#11173493 +*/ +size_t utf8_to_latin9(char *const output, const char *const input, const size_t length) +{ + unsigned char *out = (unsigned char *)output; + const unsigned char *in = (const unsigned char *)input; + const unsigned char *const end = (const unsigned char *)input + length; + unsigned int c; + + while (in < end) + if (*in < 128) + *(out++) = *(in++); /* Valid codepoint */ + else + if (*in < 192) + in++; /* 10000000 .. 10111111 are invalid */ + else + if (*in < 224) { /* 110xxxxx 10xxxxxx */ + if (in + 1 >= end) + break; + if ((in[1] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x1FU)) << 6U) + | ((unsigned int)(in[1] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 2; + + } + else + if (*in < 240) { /* 1110xxxx 10xxxxxx 10xxxxxx */ + if (in + 2 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x0FU)) << 12U) + | (((unsigned int)(in[1] & 0x3FU)) << 6U) + | ((unsigned int)(in[2] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 3; + + } + else + if (*in < 248) { /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (in + 3 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U && + (in[3] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x07U)) << 18U) + | (((unsigned int)(in[1] & 0x3FU)) << 12U) + | (((unsigned int)(in[2] & 0x3FU)) << 6U) + | ((unsigned int)(in[3] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 4; + + } + else + if (*in < 252) { /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (in + 4 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U && + (in[3] & 192U) == 128U && + (in[4] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x03U)) << 24U) + | (((unsigned int)(in[1] & 0x3FU)) << 18U) + | (((unsigned int)(in[2] & 0x3FU)) << 12U) + | (((unsigned int)(in[3] & 0x3FU)) << 6U) + | ((unsigned int)(in[4] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 5; + + } + else + if (*in < 254) { /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (in + 5 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U && + (in[3] & 192U) == 128U && + (in[4] & 192U) == 128U && + (in[5] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x01U)) << 30U) + | (((unsigned int)(in[1] & 0x3FU)) << 24U) + | (((unsigned int)(in[2] & 0x3FU)) << 18U) + | (((unsigned int)(in[3] & 0x3FU)) << 12U) + | (((unsigned int)(in[4] & 0x3FU)) << 6U) + | ((unsigned int)(in[5] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 6; + + } + else + in++; /* 11111110 and 11111111 are invalid */ + + /* Terminate the output string. */ + *out = '\0'; + + return (size_t)(out - (unsigned char *)output); +} From e46aab17880503c866f515bd677f24951d165b31 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 14:20:51 +0200 Subject: [PATCH 04/98] function newfopen to replace fopen by reading wide char strings --- src/misc/util.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/misc/util.c b/src/misc/util.c index 6801eb860..a4c14ddf3 100644 --- a/src/misc/util.c +++ b/src/misc/util.c @@ -257,3 +257,25 @@ ngdirname(const char *name) } #endif + +#ifndef EXT_ASC +#if defined(__MINGW__) || defined(_MSC_VER) +#undef BOOLEAN +#include +FILE * +newfopen(char *fn, char* md) +{ + wchar_t wfn[BSIZE_SP]; + wchar_t wmd[16]; + MultiByteToWideChar(CP_UTF8, 0, md, -1, wmd, 15); + MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, BSIZE_SP - 1); + if (MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, BSIZE_SP - 1) == 0) { + fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n", GetLastError()); + fprintf(stderr, "%s could not be converted\n", fn); + return NULL; + } + return _wfopen(wfn, wmd); +} +#endif +#endif + From 34f2f373fc7d211d5660770a57811e38a6478145 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 14:21:34 +0200 Subject: [PATCH 05/98] #define fopen newfopen and header for MINGW and MS VS --- src/include/ngspice/ngspice.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 801d70953..aafff44b6 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -218,6 +218,13 @@ extern double x_atanh(double); #endif #endif +#ifndef EXT_ASC +#if defined(__MINGW__) || defined(_MSC_VER) +#define fopen newfopen +extern FILE *newfopen(char *fn, char* md); +#endif +#endif + #if defined(__GNUC__) #define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) #elif defined(_MSC_VER) From 8d2fe137e2edab47225997049267c7185c64d5c8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Dec 2019 15:19:27 +0100 Subject: [PATCH 06/98] add angle to allow text rotation --- src/frontend/hpgl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/hpgl.c b/src/frontend/hpgl.c index 865bbb62c..806dd97cb 100644 --- a/src/frontend/hpgl.c +++ b/src/frontend/hpgl.c @@ -250,6 +250,8 @@ int GL_Arc(int x0, int y0, int r, double theta, double delta_theta) int GL_Text(char *text, int x, int y, int angle) { + NG_IGNORE(angle); + /* move to (x, y) */ NG_IGNORE(angle); From 49af98a425110a99139b90fd4ee9a5c95ce226b2 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 15:32:12 +0200 Subject: [PATCH 07/98] Add and ignore angle in fcn for text out --- src/tclspice.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tclspice.c b/src/tclspice.c index ff10db030..367eb334e 100644 --- a/src/tclspice.c +++ b/src/tclspice.c @@ -1633,6 +1633,8 @@ sp_Tk_Arc(int x0, int y0, int radius, double theta, double delta_theta) int sp_Tk_Text(char *text, int x, int y, int angle) { + NG_IGNORE(angle); + char buf[1024]; NG_IGNORE(angle); sprintf(buf, "spice_gr_Text \"%s\" %i %i", text, x, y); From 577020e9c7067919d714b63743e10d0f244b5fc4 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 15:35:03 +0200 Subject: [PATCH 08/98] Add library xft for allowing text rotation. Setting variabe 'old_x11' will retain previous behaviour. --- src/frontend/plotting/x11.c | 188 +++++++++++++++++++++++++++++------- 1 file changed, 152 insertions(+), 36 deletions(-) diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index f581028f5..e7d0d9626 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -14,6 +14,7 @@ Author: 1988 Jeffrey M. Hsu # include # include /* PN */ # include /* PN */ +# include # include "ngspice/graph.h" # include "ngspice/ftedbgra.h" @@ -37,6 +38,8 @@ Author: 1988 Jeffrey M. Hsu # include # include +#include + # ifdef DEBUG # include /* for _Xdebug */ # endif @@ -66,6 +69,11 @@ typedef struct x11info { int lastx, lasty; /* used in X_DrawLine */ int lastlinestyle; /* used in X_DrawLine */ Pixel colors[NUMCOLORS]; + /* use with xft */ + char txtcolor[16]; + char bgcolor[16]; + char fname[BSIZE_SP]; + int fsize; } X11devdep; #define DEVDEP(g) (*((X11devdep *) (g)->devdep)) @@ -91,6 +99,8 @@ static Bool noclear = False; static GRAPH *lasthardcopy; /* graph user selected */ static int X11_Open = 0; static int numdispplanes; +static int xfont_size; +static char fontname[513]; /* static functions */ static void initlinestyles(void); @@ -99,6 +109,7 @@ static void X_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy); static void linear_arc(int x0, int y0, int radius, double theta, double delta_theta); static void slopelocation(GRAPH *graph, int x0, int y0); static void zoomin(GRAPH *graph); +static int Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* name, int fsize); //XtEventHandler static void handlekeypressed(Widget w, XtPointer clientdata, XEvent *ev, Boolean *continue_dispatch); @@ -139,6 +150,9 @@ X11_Init(void) return (1); } + if (cp_getvar("old_x11", CP_BOOL, NULL)) + old_x11 = TRUE; + # ifdef DEBUG _Xdebug = 1; # endif @@ -149,9 +163,11 @@ X11_Init(void) argv[2] = "-geometry"; argv[3] = "=1x1+2+2"; */ - + /* initialze internationalization (i18n) */ + XtSetLanguageProc(NULL, NULL, NULL); /* initialize X toolkit */ toplevel = XtInitialize("ngspice", "Nutmeg", NULL, 0, &argc, argv); + setlocale(LC_NUMERIC, "C"); display = XtDisplay(toplevel); @@ -235,6 +251,12 @@ initcolors(GRAPH *graph) (void) sprintf(buf, "color%d", i); if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) (void) strcpy(colorstring, colornames[i]); + /* text color info for xft */ + if((!old_x11) && (i == 1)) + strncpy(DEVDEP(graph).txtcolor, colorstring, 15); + else if((!old_x11) && (i == 0)) + strncpy(DEVDEP(graph).bgcolor, colorstring, 15); + if (!XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)), colorstring, &visualcolor, &exactcolor)) { @@ -348,7 +370,7 @@ handle_wm_messages(Widget w, XtPointer client_data, XEvent *ev, Boolean *cont) int X11_NewViewport(GRAPH *graph) { - char fontname[513]; /* who knows . . . */ +// char fontname[513]; /* who knows . . . */ char *p, *q; Cursor cursor; XSetWindowAttributes w_attrs; @@ -376,8 +398,8 @@ X11_NewViewport(GRAPH *graph) }; static Arg viewargs[] = { { XtNresizable, (XtArgVal) TRUE }, - { XtNwidth, (XtArgVal) 300 }, - { XtNheight, (XtArgVal) 300 }, + { XtNwidth, (XtArgVal) 600 }, + { XtNheight, (XtArgVal) 500 }, { XtNright, (XtArgVal) XtChainRight } }; int trys; @@ -389,6 +411,7 @@ X11_NewViewport(GRAPH *graph) DEVDEP(graph).shell = XtCreateApplicationShell ("shell", topLevelShellWidgetClass, NULL, 0); + XtVaSetValues(DEVDEP(graph).shell, XtNtitleEncoding, XInternAtom(display, "UTF8_STRING", False), NULL); XtVaSetValues(DEVDEP(graph).shell, XtNtitle, graph->plotname, NULL); /* set up form widget */ @@ -428,32 +451,47 @@ X11_NewViewport(GRAPH *graph) /* set up fonts */ if (!cp_getvar("xfont", CP_STRING, fontname, sizeof(fontname))) (void) strcpy(fontname, DEF_FONT); + strncpy(DEVDEP(graph).fname, fontname, BSIZE_SP - 1); - for (p = fontname; *p && *p <= ' '; p++) - ; - - if (p != fontname) { - for (q = fontname; *p; *q++ = *p++) + if(old_x11) { + for (p = fontname; *p && *p <= ' '; p++) ; - *q = '\0'; - } - trys = 1; - while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { - sprintf(ErrorMessage, "can't open font %s", fontname); - strcpy(fontname, "fixed"); - if (trys > 1) { - internalerror(ErrorMessage); - RECOVERNEWVIEWPORT(); - return (1); + if (p != fontname) { + for (q = fontname; *p; *q++ = *p++) + ; + *q = '\0'; + } + trys = 1; + while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { + sprintf(ErrorMessage, "can't open font %s", fontname); + strcpy(fontname, "fixed"); + if (trys > 1) { + internalerror(ErrorMessage); + RECOVERNEWVIEWPORT(); + return (1); + } + trys += 1; } - trys += 1; } - graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - - DEVDEP(graph).font->min_bounds.lbearing + 1; - graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + - DEVDEP(graph).font->max_bounds.descent + 1; + /* font size */ + if (!cp_getvar("xfont_size", CP_NUM, &xfont_size)) + xfont_size = 16; + + if(old_x11) { + graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - + DEVDEP(graph).font->min_bounds.lbearing + 1; + graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + + DEVDEP(graph).font->max_bounds.descent + 1; + } + else { + int wl, wh; + Xget_str_length("ABCD", &wl, &wh, NULL, fontname, xfont_size); + graph->fontwidth = (int)(wl / 4); + graph->fontheight = wh; + DEVDEP(graph).fsize = xfont_size; + } XtRealizeWidget(DEVDEP(graph).shell); @@ -462,13 +500,19 @@ X11_NewViewport(GRAPH *graph) w_attrs.bit_gravity = ForgetGravity; XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, &w_attrs); + /* have to note font and set mask GCFont in XCreateGC, p.w.h. */ - gcvalues.font = DEVDEP(graph).font->fid; gcvalues.line_width = MW_LINEWIDTH; gcvalues.cap_style = CapNotLast; gcvalues.function = GXcopy; - DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + if (old_x11) { + gcvalues.font = DEVDEP(graph).font->fid; + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + } + else + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + GCLineWidth | GCCapStyle | GCFunction, &gcvalues); /* should absolute.positions really be shell.pos? */ graph->absolute.xpos = DEVDEP(graph).view->core.x; @@ -483,6 +527,7 @@ X11_NewViewport(GRAPH *graph) cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); + /* WM_DELETE_WINDOW protocol */ atom_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); atom_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); @@ -554,16 +599,59 @@ X11_Text(char *text, int x, int y, int angle) { /* We specify text position by lower left corner, so have to adjust for X11's font nonsense. */ + NG_IGNORE(angle); - if (DEVDEP(currentgraph).isopen) - XDrawString(display, DEVDEP(currentgraph).window, - DEVDEP(currentgraph).gc, x, - currentgraph->absolute.height - - (y + DEVDEP(currentgraph).font->max_bounds.descent), - text, (int) strlen(text)); + int wlen = 0, wheight = 0; - /* note: unlike before, we do not save any text here */ + if(old_x11) { + if (DEVDEP(currentgraph).isopen) + XDrawString(display, DEVDEP(currentgraph).window, + DEVDEP(currentgraph).gc, x, + currentgraph->absolute.height + - (y + DEVDEP(currentgraph).font->max_bounds.descent), + text, (int) strlen(text)); + + /* note: unlike before, we do not save any text here */ + return 0; + } + + /* new font selection with rotation */ + XftPattern *new_pat = XftPatternCreate(); // the pattern we will use for rotating + XftPatternAddString(new_pat, XFT_FAMILY, DEVDEP(currentgraph).fname); + XftPatternAddDouble (new_pat, XFT_PIXEL_SIZE, (double)DEVDEP(currentgraph).fsize); + + if(angle != 0){ + XftMatrix m; + XftMatrixInit(&m); + XftMatrixRotate(&m,cos(M_PI*angle/180.),sin(M_PI*angle/180.)); + XftPatternAddMatrix (new_pat, XFT_MATRIX,&m); + } + + XftResult rot_result; + XftPattern *rot_pat = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ + XftFont *new_font = XftFontOpenPattern(display, rot_pat); + XftPatternDestroy(new_pat); + + /* calculate and add offset, if ylabel with angle 90 */ + if (angle == 90) { + Xget_str_length(text, &wlen, &wheight, new_font, NULL, 0); + } + + Colormap cmap = DefaultColormap(display, 0); + XftColor color; + XftColorAllocName(display, DefaultVisual(display, 0), cmap, DEVDEP(currentgraph).txtcolor, &color); + XftDraw* draw = XftDrawCreate( + display, DEVDEP(currentgraph).window, DefaultVisual(display, 0), cmap + ); + /* Draw text */ + XftDrawStringUtf8( + draw, &color, new_font, + x + (int)(1.5 * wlen), currentgraph->absolute.height - y + (int)(0.5 * wheight), (FcChar8*)text, strlen(text) + ); + XftFontClose( display, new_font); + XftDrawDestroy(draw); + XftColorFree(display, DefaultVisual(display, 0), cmap, &color); return 0; } @@ -828,8 +916,9 @@ zoomin(GRAPH *graph) "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e; setplot $curplot\n", buf2, graph->commandline, fx0, fx1, fy0, fy1); } else { - (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", - graph->commandline, fx0, fx1, fy0, fy1); + /* set the foreground and background colors to the "calling" window's colors */ + (void) sprintf(buf, "set color0=%s; set color1=%s; %s xlimit %e %e ylimit %e %e\n", + DEVDEP(graph).bgcolor, DEVDEP(graph).txtcolor, graph->commandline, fx0, fx1, fy0, fy1); } /* don't use the following if using GNU Readline or BSD EditLine */ @@ -906,7 +995,8 @@ void RemoveWindow(GRAPH *graph) /* MW. Not sure but DestroyGraph might free() too much - try Xt...() first */ XtUnmapWidget(DEVDEP(graph).shell); XtDestroyWidget(DEVDEP(graph).shell); - XFreeFont(display, DEVDEP(graph).font); + if (old_x11) + XFreeFont(display, DEVDEP(graph).font); XFreeGC(display, DEVDEP(graph).gc); } @@ -1105,6 +1195,32 @@ linear_arc(int x0, int y0, int radius, double theta, double delta_theta) } } + /* After font selection for XftTextExtentsUtf8 + * to measure character string length. + * Same as rotation below, but 0 angle */ +static int +Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* foname, int fsize) { + XGlyphInfo extents; + XftFont* hfont = NULL; + /* if font name and font size are given */ + if (gfont == NULL) { + XftPattern *ext_pat = XftPatternCreate(); // the pattern we will use for rotating + XftPatternAddString(ext_pat, XFT_FAMILY, foname); + XftPatternAddDouble(ext_pat, XFT_PIXEL_SIZE, (double)fsize); + XftResult ext_result; + hfont = gfont = XftFontOpenPattern(display, XftFontMatch(display, 0, ext_pat, &ext_result)); + XftTextExtentsUtf8(display, gfont, (XftChar8 *)text, strlen(text), &extents); + XftPatternDestroy(ext_pat); + } + XftTextExtentsUtf8( display, gfont, (XftChar8 *)text, strlen(text), &extents ); + if(hfont) + XftFontClose( display,hfont); + + /* size of the string */ + *wlen = extents.width; + *wheight = extents.height; + return 0; +} #else From c0b9ef41b14e1a8ac5cfd90b74f988e706304c88 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Dec 2019 18:05:35 +0100 Subject: [PATCH 09/98] For UNICODE use char in comparison to ' ' only as unsigned char --- src/frontend/numparam/spicenum.c | 6 +++--- src/frontend/numparam/xpressn.c | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 52255a050..b9cde18fe 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -81,7 +81,7 @@ stripsomespace(DSTRINGPTR dstr_p, bool incontrol) char *s = ds_get_buf(dstr_p); int i = 0; - while (s[i] && (s[i] <= ' ')) + while (s[i] && ((unsigned char)s[i] <= ' ')) i++; if ((i > 0) && s[i] && strchr(markers, s[i])) @@ -116,7 +116,7 @@ stripbraces(DSTRINGPTR dstr_p) pscopy(&tstr, s, brace); - if (brace[-1] > ' ') + if ((unsigned char)brace[-1] > ' ') cadd(&tstr, ' '); cadd(&tstr, ' '); @@ -127,7 +127,7 @@ stripbraces(DSTRINGPTR dstr_p) } cadd(&tstr, ' '); - if (*j_ptr >= ' ') + if ((unsigned char)(* j_ptr) >= ' ') cadd(&tstr, ' '); int ilen = (int) ds_get_length(&tstr); diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 78fb231c9..006b0dc60 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -509,15 +509,15 @@ defsubckt(dico_t *dico, const struct card *card) while (*s && (*s != '.')) s++; /* skip 1st dotword */ - while (*s && (*s > ' ')) + while (*s && ((unsigned char) (*s) > ' ')) s++; - while (*s && (*s <= ' ')) + while (*s && ((unsigned char) (*s) <= ' ')) s++; /* skip blank */ s_end = s; - while (*s_end && (*s_end > ' ')) + while (*s_end && ((unsigned char) (*s_end) > ' ')) s_end++; if (s_end > s) { @@ -574,7 +574,7 @@ keyword(const char *keys, const char *s, const char *s_end) const char *p = s; while ((p < s_end) && (*p == *keys)) p++, keys++; - if ((p >= s_end) && (*keys <= ' ')) + if ((p >= s_end) && ((unsigned char) (*keys) <= ' ')) return j; keys = strchr(keys, ' '); if (!keys) @@ -723,7 +723,7 @@ fetchoperator(dico_t *dico, level = 8; } else { state = S_init; - if (c > ' ') + if ((unsigned char) c > ' ') error = message(dico, "Syntax error: letter [%c]\n", c); } @@ -859,7 +859,7 @@ formula(dico_t *dico, const char *s, const char *s_end, bool *perror) } /* trim trailing whitespace */ - while ((s_end > s) && (s_end[-1] <= ' ')) + while ((s_end > s) && ((unsigned char) (s_end[-1]) <= ' ')) s_end--; state = S_init; @@ -1222,7 +1222,7 @@ getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) const char *p; nupa_type tpe; - while ((s < s_end - 1) && (*s <= ' ')) + while ((s < s_end - 1) && ((unsigned char)(* s) <= ' ')) s++; /*white space ? */ if (*s == '"') { /* string constant */ @@ -1235,7 +1235,7 @@ getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) do p++; - while ((p < s_end) && (*p <= ' ')); + while ((p < s_end) && ((unsigned char)(*p) <= ' ')); tpe = NUPA_STRING; @@ -1309,11 +1309,11 @@ nupa_assignment(dico_t *dico, const char *s, char mode) DS_CREATE(tstr, 200); /* temporary dstrings */ DS_CREATE(ustr, 200); - while ((p < s_end) && (*p <= ' ')) + while ((p < s_end) && ((unsigned char) (*p) <= ' ')) p++; if (*p == '.') /* skip any dot keyword */ - while (*p > ' ') + while ((unsigned char) (*p) > ' ') p++; while (p < s_end) { @@ -1509,7 +1509,7 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, jp = getexpress(NULL, &ustr, jp); } else { jp++; - if (*kp > ' ') + if ((unsigned char) (*kp) > ' ') message(dico, "Subckt call, symbol %c not understood\n", *kp); } From 8457c6dcf6e70655bdf814d245a0b45e734e1e17 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 16:05:16 +0200 Subject: [PATCH 10/98] return extended ascii as alpha --- src/frontend/numparam/mystring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/numparam/mystring.c b/src/frontend/numparam/mystring.c index d699522f6..8918de630 100644 --- a/src/frontend/numparam/mystring.c +++ b/src/frontend/numparam/mystring.c @@ -142,7 +142,7 @@ alfa(char c) return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || - c == '_' || c == '[' || c == ']'; + c == '_' || c == '[' || c == ']' || ((c) & 0200); } From 095fde74c4c2c960834ee178468e279c71674d92 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 19:44:43 +0200 Subject: [PATCH 11/98] add wide char for string i/o under Windows add utf-8 systax check --- src/frontend/inpcom.c | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index d26fb674a..78c6e8866 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -181,6 +181,15 @@ static void pspice_compat_a(struct card *oldcard); static struct card *ltspice_compat(struct card *oldcard); static void ltspice_compat_a(struct card *oldcard); +#if defined(__MINGW32__) || defined(_MSC_VER) +#ifndef EXT_ASC +static int newstat(const char *name, struct _stat *st); +#endif +#endif +#ifndef EXT_ASC +static void utf8_syntax_check(struct card *deck); +#endif + struct inp_read_t { struct card *cc; int line_number; @@ -619,6 +628,10 @@ struct card *inp_readall(FILE *fp, const char *dir_name, struct card *working = cc->nextcard; delete_libs(); + +#ifndef EXT_ASC + utf8_syntax_check(working); +#endif /* some syntax checks, including title line */ inp_check_syntax(cc); @@ -1282,6 +1295,13 @@ FILE *inp_pathopen(const char *name, const char *mode) } /* end of function inp_pathopen */ +/* for MultiByteToWideChar */ +#if defined(__MINGW32__) || defined(_MSC_VER) +#ifndef EXT_ASC +#undef BOOLEAN +#include +#endif +#endif /*-------------------------------------------------------------------------* Look up the variable sourcepath and try everything in the list in order @@ -1317,6 +1337,17 @@ static char *inp_pathresolve(const char *name) /* just try it */ if (stat(name, &st) == 0) return copy(name); + +#if defined(__MINGW32__) || defined(_MSC_VER) + wchar_t wname[BSIZE_SP]; + if (MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, 2 * (int)strlen(name) + 1) == 0) { + fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n", GetLastError()); + fprintf(stderr, "%s could not be converted\n", name); + return NULL; + } + if (_waccess(wname, 0) == 0) + return copy(name); +#endif /* fail if this was an absolute filename or if there is no sourcepath var */ @@ -8604,3 +8635,82 @@ static void inp_rem_unused_models(struct nscope *root, struct card *deck) // disable unused .model lines, and free the models assoc lists rem_unused_xxx(root); } + +/* Markus Kuhn -- 2005-03-30 + * License: Modified BSD (see http://www.cl.cam.ac.uk/~mgk25/short-license.html) + * The utf8_check() function scans the '\0'-terminated string starting + * at s. It returns a pointer to the first byte of the first malformed + * or overlong UTF-8 sequence found, or NULL if the string contains + * only correct UTF-8. It also spots UTF-8 sequences that could cause + * trouble if converted to UTF-16, namely surrogate characters + * (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF).*/ +#ifndef EXT_ASC +static unsigned char* +utf8_check(unsigned char *s) +{ + while (*s) { + if (*s < 0x80) + /* 0xxxxxxx */ + s++; + else if ((s[0] & 0xe0) == 0xc0) { + /* 110XXXXx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[0] & 0xfe) == 0xc0) /* overlong? */ + return s; + else + s += 2; + } + else if ((s[0] & 0xf0) == 0xe0) { + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xef && s[1] == 0xbf && + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ + return s; + else + s += 3; + } + else if ((s[0] & 0xf8) == 0xf0) { + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80 || + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */ + return s; + else + s += 4; + } + else + return s; + } + + return NULL; +} + +/* Scan through input deck and check for utf-8 syntax errors */ +static void +utf8_syntax_check(struct card *deck) +{ + struct card *card; + unsigned char *s; + + for (card = deck; card; card = card->nextcard) { + + char *curr_line = card->line; + + if (*curr_line == '*') + continue; + + s = utf8_check((unsigned char*)curr_line); + + if (s) { + fprintf(stderr, "Error: UTF-8 syntax error in line %d at %s\n", card->linenum_orig, s); + controlled_exit(1); + } + } +} +#endif + From de7bd1ac7c08b7b11fb1e2f62a9ac87af540fb35 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 20:43:09 +0200 Subject: [PATCH 12/98] some utf-8 examples please apologize for the nonsense texts --- examples/utf-8/стекло/ext-ascii-1.cir | 27 ++++++ examples/utf-8/стекло/ext-ascii-2.cir | 25 ++++++ examples/utf-8/стекло/ext-utf8-2.cir | 27 ++++++ examples/utf-8/стекло/ext-utf8-cyg2.cir | 42 +++++++++ examples/utf-8/стекло/있어요/adder_mos.cir | 82 ++++++++++++++++++ examples/utf-8/стекло/있어요/adder_mos3.cir | 85 +++++++++++++++++++ examples/utf-8/стекло/있어요/ext-utf8-1.cir | 39 +++++++++ .../utf-8/стекло/있어요/ext-utf8-2-있어요.cir | 46 ++++++++++ examples/utf-8/стекло/있어요/ext-utf8-2.cir | 46 ++++++++++ examples/utf-8/стекло/있어요/ext-utf8-3.cir | 33 +++++++ examples/utf-8/стекло/있어요/ext-utf8-4.cir | 40 +++++++++ examples/utf-8/стекло/있어요/utf-8-inv.cir | 52 ++++++++++++ examples/utf-8/стекло/있어요/utf-8-inv_w.cir | 53 ++++++++++++ 13 files changed, 597 insertions(+) create mode 100644 examples/utf-8/стекло/ext-ascii-1.cir create mode 100644 examples/utf-8/стекло/ext-ascii-2.cir create mode 100644 examples/utf-8/стекло/ext-utf8-2.cir create mode 100644 examples/utf-8/стекло/ext-utf8-cyg2.cir create mode 100644 examples/utf-8/стекло/있어요/adder_mos.cir create mode 100644 examples/utf-8/стекло/있어요/adder_mos3.cir create mode 100644 examples/utf-8/стекло/있어요/ext-utf8-1.cir create mode 100644 examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir create mode 100644 examples/utf-8/стекло/있어요/ext-utf8-2.cir create mode 100644 examples/utf-8/стекло/있어요/ext-utf8-3.cir create mode 100644 examples/utf-8/стекло/있어요/ext-utf8-4.cir create mode 100644 examples/utf-8/стекло/있어요/utf-8-inv.cir create mode 100644 examples/utf-8/стекло/있어요/utf-8-inv_w.cir diff --git a/examples/utf-8/стекло/ext-ascii-1.cir b/examples/utf-8/стекло/ext-ascii-1.cir new file mode 100644 index 000000000..72c3b45d8 --- /dev/null +++ b/examples/utf-8/стекло/ext-ascii-1.cir @@ -0,0 +1,27 @@ +* test de titre + +.control + +set hcopydevtype = postscript +set hcopypscolor=1 +set color2=rgb:F/0/0 + +let x = vector(5) +let y = exp(x) + +plot y vs x xlabel 'Mon x' ylabel 'Mon y' +hardcopy plot_1.ps y vs x xlabel 'Mon X' ylabel 'Mon Y' + +plot y vs x xlabel 'Mon x' title 'Mon titre' +hardcopy plot_2.ps y vs x xlabel 'Mon x' title 'Mon titre' + +plot y vs x xlabel test +hardcopy plot_3.ps y vs x xlabel test + +plot y vs x +hardcopy plot_4.ps y vs x + +plot y vs x xlabel 'Labellis X' ylabel 'Labellise Y' title 'Titr' +hardcopy plot_5.ps y vs x xlabel 'Labellis X' title 'Labellis Y' title 'Titr' + +.endc diff --git a/examples/utf-8/стекло/ext-ascii-2.cir b/examples/utf-8/стекло/ext-ascii-2.cir new file mode 100644 index 000000000..f0122d6e3 --- /dev/null +++ b/examples/utf-8/стекло/ext-ascii-2.cir @@ -0,0 +1,25 @@ +* test de titr + +.control +set encoding=extended_ascii +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +setcf hcopyfont="Garamond" +set hcopyfontsize=14 + +let x = vector(5) +let y = exp(x) +setcf wfont="Garamond Fett" +set wfont_size=16 +plot y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' +plot y vs x xlabel 'Labellis X' title 'Titr' +plot y vs x+0.001 xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' loglog +plot y vs x+0.001 xlabel 'Labellis X' title 'Titr' loglog + +hardcopy plot_5.ps y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' +shell Start /B plot_5.ps +write D:\Spice_general\tests\ext_unic_test.raw y x +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir new file mode 100644 index 000000000..abaeb4d40 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -0,0 +1,27 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +setcf hcopyfont=Arial +set hcopyfontsize=14 + +let x = vector(5) +let y = exp(x) +setcf wfont=Arial +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-cyg2.cir b/examples/utf-8/стекло/ext-utf8-cyg2.cir new file mode 100644 index 000000000..f77a036e0 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-cyg2.cir @@ -0,0 +1,42 @@ +* test de titré + +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +setcf hcopyfont=Arial +set hcopyfontsize=14 +set color0="black" +set color1="white" +let x = vector(5) +let y = exp(x) +setcf xfont="Times New Roman" +set xfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +set color0="white" +set color1="black" +set xfont_size=16 +setcf xfont="Arial" +plot y vs x xlabel 'Я могу есть стекло, оно мне не вредит' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Я могу есть стекло, оно мне не вредит' +set color0="yellow" +set color1="red" +set xfont_size=18 +setcf xfont="Noto Sans CJK JP Medium" +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog + +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体。 + +setcf sourcepath = ( "D:/Spice_general/tests/utf-8/стекло/있어요" ) +source ext-utf8-2.cir + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/adder_mos.cir b/examples/utf-8/стекло/있어요/adder_mos.cir new file mode 100644 index 000000000..3f0e7af7c --- /dev/null +++ b/examples/utf-8/стекло/있어요/adder_mos.cir @@ -0,0 +1,82 @@ + 유리를 - 4 BIT ALL-NAND-GATE BINARY ADDER + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAND in1 in2 out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out in2 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 in2 0 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out in1 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out in1 net.1 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAND + +.SUBCKT ONEBIT 1 2 3 4 5 6 +* NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC +X1 1 2 7 6 NAND +X2 1 7 8 6 NAND +X3 2 7 9 6 NAND +X4 8 9 10 6 NAND +X5 3 10 11 6 NAND +X6 3 11 12 6 NAND +X7 10 11 13 6 NAND +X8 12 13 4 6 NAND +X9 11 7 5 6 NAND +.ENDS ONEBIT + +.SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9 +* NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1, +* CARRY-IN, CARRY-OUT, VCC +X1 1 2 7 5 10 9 ONEBIT +X2 3 4 10 6 8 9 ONEBIT +.ENDS TWOBIT + +.SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2), +* OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC +X1 1 2 3 4 9 10 13 16 15 TWOBIT +X2 5 6 7 8 11 12 16 14 15 TWOBIT +.ENDS FOURBIT + +*** POWER +VCC 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B 2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) +VIN2A 3 0 DC 0 PULSE(0 3 0 5NS 5NS 50NS 200NS) +VIN2B 4 0 DC 0 PULSE(0 3 0 5NS 5NS 90NS 400NS) +VIN3A 5 0 DC 0 PULSE(0 3 0 5NS 5NS 170NS 800NS) +VIN3B 6 0 DC 0 PULSE(0 3 0 5NS 5NS 330NS 1600NS) +VIN4A 7 0 DC 0 PULSE(0 3 0 5NS 5NS 650NS 3200NS) +VIN4B 8 0 DC 0 PULSE(0 3 0 5NS 5NS 1290NS 6400NS) + +*** DEFINE NOMINAL CIRCUIT +X1 1 2 3 4 5 6 7 8 9 10 11 12 0 13 99 FOURBIT + +.option noinit acct +.TRAN 500p 640NS +* save inputs +.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +save x1.x1.x1.7 V(9) V(10) V(11) V(12) V(13) +run +display +* plot the inputs, use offset to plot on top of each other +plot v(1) v(2)+4 v(3)+8 v(4)+12 v(5)+16 v(6)+20 v(7)+24 v(8)+28 +* plot the outputs, use offset to plot on top of each other +plot v(9) v(10)+4 v(11)+8 v(12)+12 v(13)+16 +endif +.endc + +.END diff --git a/examples/utf-8/стекло/있어요/adder_mos3.cir b/examples/utf-8/стекло/있어요/adder_mos3.cir new file mode 100644 index 000000000..e84d6a57e --- /dev/null +++ b/examples/utf-8/стекло/있어요/adder_mos3.cir @@ -0,0 +1,85 @@ + 4 BIT ALL-NAND-GATE BINARY ADDER with node names 能 and せん + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAND in1 in2 out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out in2 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 in2 0 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out in1 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out in1 net.1 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAND + +.SUBCKT ONEдBIT 能 2 せん 4 5 6 +* NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC +X1 能 2 7 6 NAND +X2 能 7 8 6 NAND +X나는 2 7 9 6 NAND +X4 8 9 10 6 NAND +X5 せん 10 11 6 NAND +X6 せん 11 12 6 NAND +X7 10 11 13 6 NAND +XЯ8 12 13 4 6 NAND +XЯ9 11 7 5 6 NAND +.ENDS ONEдBIT + +.SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9 +* NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1, +* CARRY-IN, CARRY-OUT, VCC +X1 1 2 7 5 10 9 ONEдBIT +X2 3 4 10 6 8 9 ONEдBIT +.ENDS TWOBIT + +.SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2), +* OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC +X1 1 2 3 4 9 10 13 16 15 TWOBIT +X2 5 6 7 8 11 12 16 14 15 TWOBIT +.ENDS FOURBIT + +*** POWER +V을을 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B 2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) +VIN2A 3 0 DC 0 PULSE(0 3 0 5NS 5NS 50NS 200NS) +VIN2B 4 0 DC 0 PULSE(0 3 0 5NS 5NS 90NS 400NS) +VIN3A 5 0 DC 0 PULSE(0 3 0 5NS 5NS 170NS 800NS) +VIN3B 6 0 DC 0 PULSE(0 3 0 5NS 5NS 330NS 1600NS) +VIN4A 7 0 DC 0 PULSE(0 3 0 5NS 5NS 650NS 3200NS) +VIN4B 8 0 DC 0 PULSE(0 3 0 5NS 5NS 1290NS 6400NS) + +*** DEFINE NOMINAL CIRCUIT +X1 1 2 3 4 5 6 7 8 9 10 11 身12 0 Я13 99 FOURBIT + +.option noinit acct +.TRAN 500p 6400NS +* save inputs +.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=16 +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +save x1.x1.x1.7 V(9) V(10) V(11) V(身12) V(Я13) +run +display +* plot the inputs, use offset to plot on top of each other +plot v(1) v(2)+4 v(3)+8 v(4)+12 v(5)+16 v(6)+20 v(7)+24 v(8)+28 +* plot the outputs, use offset to plot on top of each other +plot v(9) v(10)+4 v(11)+8 v(身12)+12 v(Я13)+16 +endif +.endc + +.END diff --git a/examples/utf-8/стекло/있어요/ext-utf8-1.cir b/examples/utf-8/стекло/있어요/ext-utf8-1.cir new file mode 100644 index 000000000..47758fa65 --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-1.cir @@ -0,0 +1,39 @@ +* test de titré +.control + +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=16 +* for LINUX +*setcf xfont='Noto Sans Korean' + +let x = vector(5) +let y = exp(x) +setcf wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 11' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 12 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 13 私はガラスを食べられます。それは私を傷つけません' loglog +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 14 我能吞下玻璃而不伤身体。' loglog + +* for CYGWIN +*setcf xfont='Adobe Times' +* for LINUX +setcf xfont='Efont Biwidth' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 15' loglog + +write D:/Spice_general/tests/utf-8/'стекло'/'있어요'/ext-utf8-1.out x y + +setcf sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) +*setcf sourcepath = ( './utf-8/стекло/있어요' ) +source ext-utf8-2.cir + +*source 'D:/Spice_general/tests/utf-8/стекло/있어요/ext-utf8-2.cir' + +echo 私はガラスを食べられます。それは私を傷つけません +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir new file mode 100644 index 000000000..00dd8d04d --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir @@ -0,0 +1,46 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +*setcf hcopyfont=Arial +* +*setcf hcopyfont='Nimbus Mono-Regular' +* for CYGWIN +setcf hcopyfont='NimbusMonL-Bold' +*setcf hcopyfont='URWGothicL-Book' +set hcopyfontsize=14 + +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=18 +*setcf xfont='Noto Sans Japanese' + +let x = vector(5) +let y = exp(x) +setcf wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' +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 +*LINUX +*setcf xfont='Noto Sans Korean' +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog +* for CYGWIN +setcf xfont='Times New Roman' +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é Äü @µ€~' +* for MS Windows only +*shell Start /B plot_5.ps +* for CYGWIN +shell xterm -e gs plot_5.ps & + +echo 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 +echo אני יכול לאכול זכוכית וזה לא מזיק לי. + +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2.cir b/examples/utf-8/стекло/있어요/ext-utf8-2.cir new file mode 100644 index 000000000..00dd8d04d --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-2.cir @@ -0,0 +1,46 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +*setcf hcopyfont=Arial +* +*setcf hcopyfont='Nimbus Mono-Regular' +* for CYGWIN +setcf hcopyfont='NimbusMonL-Bold' +*setcf hcopyfont='URWGothicL-Book' +set hcopyfontsize=14 + +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=18 +*setcf xfont='Noto Sans Japanese' + +let x = vector(5) +let y = exp(x) +setcf wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' +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 +*LINUX +*setcf xfont='Noto Sans Korean' +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog +* for CYGWIN +setcf xfont='Times New Roman' +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é Äü @µ€~' +* for MS Windows only +*shell Start /B plot_5.ps +* for CYGWIN +shell xterm -e gs plot_5.ps & + +echo 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 +echo אני יכול לאכול זכוכית וזה לא מזיק לי. + +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir new file mode 100644 index 000000000..befc033ac --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -0,0 +1,33 @@ +* test de titré 있어요 +* appologize for nonsense text + +.control + +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=18 + +let x = vector(5) +let y = exp(x) +setcf wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 11' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 12 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 13 私はガラスを食べられます。それは私を傷つけません' loglog +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 14 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog + +* for CYGWIN +setcf xfont='Times New Roman' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 15' loglog + +setcf sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) +source ext-utf8-4.cir + +* better to put ouput into single quotes +echo 1 '私はガラスを食べられます。それは私を傷つけません' +echo 2 '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel '있어요 tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-4.cir b/examples/utf-8/стекло/있어요/ext-utf8-4.cir new file mode 100644 index 000000000..db4c24e7c --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-4.cir @@ -0,0 +1,40 @@ +* test de titré それは私を傷つけません +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +*setcf hcopyfont=Arial +* for CYGWIN +setcf hcopyfont='NimbusMono-Regular' +set hcopyfontsize=14 + +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=16 + +let x = vector(5) +let y = exp(x) +setcf wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' +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 +* for CYGWIN +setcf xfont='Times New Roman' +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é Äü @µ€~' +* for MS Windows only +*shell Start /B plot_5.ps +* for CYGWIN +shell xterm -e gs plot_5.ps & + +echo 3 ' 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 ' +echo 4 אני יכול לאכול זכוכית וזה לא מזיק לי. + +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/utf-8-inv.cir b/examples/utf-8/стекло/있어요/utf-8-inv.cir new file mode 100644 index 000000000..8853bd3c1 --- /dev/null +++ b/examples/utf-8/стекло/있어요/utf-8-inv.cir @@ -0,0 +1,52 @@ + 4 BIT ALL-NAND-GATE BINARY ADDER with node names 能 and せん + +.param W咦 = 3u + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAдND 能 せん out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out せん Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 せん 0 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out 能 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out 能 net.1 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAдND + +X않1 1 は2 7 99 NAдND + +*** POWER +V을을 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B は2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) + +.option noinit acct +.TRAN 500p 6400NS +* save inputs +.save V(1) V(は2) V(7) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=16 +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +run +display +* plot the inputs and outputs, use offset to plot on top of each other +let れ1 = 4 +let れ2 = 8 +plot v(1) v(は2)+れ1 v(7)+れ2 +endif +.endc + +.END diff --git a/examples/utf-8/стекло/있어요/utf-8-inv_w.cir b/examples/utf-8/стекло/있어요/utf-8-inv_w.cir new file mode 100644 index 000000000..adeccc347 --- /dev/null +++ b/examples/utf-8/стекло/있어요/utf-8-inv_w.cir @@ -0,0 +1,53 @@ + 4 BIT ALL-NAND-GATE BINARY ADDER with node names 能 and せん + +.param W咦 = 3u + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAдND 能 せん out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out せん Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 せん 0 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out 能 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out 能 net.1 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAдND + +X않1 1 は2 7 99 NAдND + +*** POWER +V을을 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B は2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) + +.option noinit acct +.TRAN 500p 500NS +* save inputs +.save V(1) V(は2) V(7) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +* for CYGWIN +setcf xfont='Noto Sans CJK JP Medium' +set xfont_size=16 + +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +run +display +* plot the inputs and outputs, use offset to plot on top of each other +let れ1 = 4 +let れ2 = 8 +plot v(1) v(は2)+れ1 v(7)+れ2 +endif +.endc + +.END From a08a373cce78e176d95dd64614ad680ea64fb949 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 21:03:01 +0200 Subject: [PATCH 13/98] freetype includes, checking for Xft lib, fontconfig --- configure.ac | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.ac b/configure.ac index c969c1603..f28ea1083 100644 --- a/configure.ac +++ b/configure.ac @@ -680,6 +680,7 @@ fi # (The previous order was -lX11 -lXt -lXext -lXmu -lXaw) if test "x$no_x" != xyes ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/freetype2" AC_CHECK_LIB([Xaw], [main], [X_LIBS="$X_LIBS -lXaw"], [AC_MSG_ERROR([Couldn't find Xaw library])], [$X_LIBS $X_EXTRA_LIBS]) AC_CHECK_LIB([Xmu], [main], [X_LIBS="$X_LIBS -lXmu"], @@ -687,7 +688,11 @@ if test "x$no_x" != xyes ; then X_LIBS="$X_LIBS -lXt" AC_CHECK_LIB([Xext], [XShmAttach], [X_LIBS="$X_LIBS -lXext"], [AC_MSG_ERROR([Couldn't find Xext library])], [$X_LIBS $X_EXTRA_LIBS]) + AC_CHECK_LIB([Xft], [main], [X_LIBS="$X_LIBS -lXft"], + [AC_MSG_ERROR([Couldn't find Xft library])], [$X_LIBS $X_EXTRA_LIBS]) X_LIBS="$X_LIBS -lX11" + AC_CHECK_LIB([fontconfig], [main], [X_LIBS="$X_LIBS -lfontconfig"], + [AC_MSG_ERROR([Couldn't find fontconfig library])], [$X_LIBS $X_EXTRA_LIBS]) has_no_x=false else AC_DEFINE([X_DISPLAY_MISSING]) From b1b253d845f4ded3a49645c28dd053b4a691e7b9 Mon Sep 17 00:00:00 2001 From: h_vogt Date: Wed, 4 Oct 2017 21:11:42 +0200 Subject: [PATCH 14/98] short description of utf-8+1 branch contents --- README.utf8 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README.utf8 diff --git a/README.utf8 b/README.utf8 new file mode 100644 index 000000000..1def2c79c --- /dev/null +++ b/README.utf8 @@ -0,0 +1,14 @@ +use utf-8 for encoding of strings, this enables UNICODE +international characters sets (of nearly any language) +in titles, labels, file and folder names. + +Windows uses utf-16 and conversion function between utf-8 +and utf-16, if access to Windows API functions is needed. +A special fopen has been defined. + +In addition, plot labels on the y axis now are placed +vertically, 90°, by using WWindows API or Linux Xft library. + +Postscript plotting uses only a UNICODE subset, t.b.d.. + +Better looking fonts are now used for labelling. From 7bf2fbde75ae6117ae7f511e8db1603d6c233590 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 5 Oct 2017 12:47:16 +0200 Subject: [PATCH 15/98] add missing declaration of old_x11 --- src/frontend/plotting/grid.c | 4 ++++ src/frontend/plotting/x11.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c index 31d04a51e..588da69ae 100644 --- a/src/frontend/plotting/grid.c +++ b/src/frontend/plotting/grid.c @@ -36,6 +36,10 @@ extern bool old_x11; extern int X11_GetLenStr(GRAPH *gr, char* instring); #endif +#ifndef X_DISPLAY_MISSING +extern bool old_x11; +#endif + #define RAD_TO_DEG (180.0 / M_PI) #define RELPOSXUNIT 0.6 /* old position of the UNIT label */ diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index e7d0d9626..c846218e0 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -60,6 +60,8 @@ Author: 1988 Jeffrey M. Hsu #define NUMCOLORS 20 +bool old_x11 = FALSE; /* if FALSE, use xft, if TRUE use old X11 text output */ + typedef struct x11info { Window window; int isopen; From 7f301cbe334b488fdfae7c32e75165904eb94d19 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Oct 2017 22:54:42 +0200 Subject: [PATCH 16/98] Enable separate linewidths for grids and graphs. New variable gridwidth overrides xbrushwidth for graphs. Fcn DevDrawLine() with boolean flag if grid is plotted. Postscript, Gnuplot and X11 not (yet) supported. --- src/frontend/display.c | 4 +-- src/frontend/display.h | 2 +- src/frontend/plotting/graf.c | 10 ++++---- src/frontend/plotting/plot5.c | 5 +++- src/frontend/plotting/x11.c | 3 ++- src/frontend/postsc.c | 4 ++- src/frontend/wdisp/winprint.c | 46 ++++++++++++++++++----------------- src/frontend/wdisp/winprint.h | 2 +- src/include/ngspice/ftedev.h | 2 +- 9 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/frontend/display.c b/src/frontend/display.c index 0faa71b27..54595883f 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -233,9 +233,9 @@ DevClear(void) void -DevDrawLine(int x1, int y1, int x2, int y2) +DevDrawLine(int x1, int y1, int x2, int y2, bool isgrid) { - dispdev->DrawLine (x1, y1, x2, y2); + dispdev->DrawLine (x1, y1, x2, y2, isgrid); } diff --git a/src/frontend/display.h b/src/frontend/display.h index 6d4f10bf5..a3ff68d4b 100644 --- a/src/frontend/display.h +++ b/src/frontend/display.h @@ -17,7 +17,7 @@ void DevInit(void); int NewViewport(GRAPH *pgraph); void DevClose(void); void DevClear(void); -void DevDrawLine(int x1, int y1, int x2, int y2); +void DevDrawLine(int x1, int y1, int x2, int y2, bool isgrid); void DevDrawArc(int x0, int y0, int radius, double theta, double delta_theta); void DevDrawText(char *text, int x, int y, int angle); void DefineColor(int colorid, double red, double green, double blue); diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 15ad1bdb8..e5fde6f95 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -294,9 +294,9 @@ void gr_point(struct dvec *dv, case PLOT_MONOLIN: /* If it's a linear plot, ignore first point since we don't want to connect with oldx and oldy. */ - if (np) { - DevDrawLine(fromx, fromy, tox, toy); - } + if (np) + DevDrawLine(fromx, fromy, tox, toy, FALSE); + if ((tics = currentgraph->ticdata) != NULL) { for (; *tics < HUGE; tics++) if (*tics == (double) np) { @@ -326,7 +326,7 @@ void gr_point(struct dvec *dv, DatatoScreen(currentgraph, 0.0, currentgraph->datawindow.ymin, &dummy, &ymin); - DevDrawLine(tox, ymin, tox, toy); + DevDrawLine(tox, ymin, tox, toy, FALSE); break; case PLOT_POINT: /* Here, gi_linestyle is the character used for the point. */ @@ -477,7 +477,7 @@ void drawlegend(GRAPH *graph, int plotno, struct dvec *dv) } else { SetLinestyle(dv->v_linestyle); - DevDrawLine(x, i, x_base, i); + DevDrawLine(x, i, x + graph->viewport.width / 20, i, FALSE); } SetColor(1); DevDrawText(dv->v_name, x_base + graph->fontwidth, y, 0); diff --git a/src/frontend/plotting/plot5.c b/src/frontend/plotting/plot5.c index 5c4db679c..cc3aeec47 100644 --- a/src/frontend/plotting/plot5.c +++ b/src/frontend/plotting/plot5.c @@ -108,8 +108,11 @@ int Plt5_Clear(void) } -int Plt5_DrawLine(int x1, int y1, int x2, int y2) +int +Plt5_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); + putc('l', plotfile); putsi(x1); putsi(y1); diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index c846218e0..0c63b62fb 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -560,8 +560,9 @@ X11_Close(void) int -X11_DrawLine(int x1, int y1, int x2, int y2) +X11_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); if (DEVDEP(currentgraph).isopen) XDrawLine(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 966c35e75..3ff5ab910 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -280,8 +280,10 @@ int PS_Clear(void) } -int PS_DrawLine(int x1, int y1, int x2, int y2) +int +PS_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); /* note: this is not extendible to more than one graph => will have to give NewViewport a writeable graph XXX */ diff --git a/src/frontend/wdisp/winprint.c b/src/frontend/wdisp/winprint.c index e81fff873..4f8db2192 100644 --- a/src/frontend/wdisp/winprint.c +++ b/src/frontend/wdisp/winprint.c @@ -31,7 +31,7 @@ #pragma hdrstop #endif /* _MSC_VER */ -#include "winprint.h" /* function prototypes */ +#include "winprint.h" /* function prototypes */ /* Typen */ typedef struct { /* Extra Printdaten */ @@ -126,7 +126,7 @@ WPRINT_Init() gibt 0 zurueck, falls kein Fehler auftrat. int WPRINT_Init(void) { int pWidth; - int pHeight; + int pHeight; /* Printer-DC holen */ if (!PrinterDC) { @@ -198,19 +198,19 @@ int WPRINT_Init(void) /* Initialisierungen des Display-Descriptors */ dispdev->width = PrinterWidth; - dispdev->height = PrinterHeight; + dispdev->height = PrinterHeight; dispdev->numlinestyles = NumLines; dispdev->numcolors = NumPrintColors; /* Farben initialisieren */ - ColorTable[0] = RGB(255,255,255); /* Weisz */ - ColorTable[1] = RGB(0, 0, 0); /* Schwarz */ + ColorTable[0] = RGB(255,255,255); /* Weisz */ + ColorTable[1] = RGB(0, 0, 0); /* Schwarz */ /* LineStyles initialisieren */ LineTable[0] = PS_SOLID; - LineTable[1] = PS_DOT; /* Gitter */ + LineTable[1] = PS_DOT; /* Gitter */ LineTable[2] = PS_SOLID; /* Erste Linie */ - LineTable[3] = PS_DOT; /* Zweite Linie */ + LineTable[3] = PS_DOT; /* Zweite Linie */ LineTable[4] = PS_DASH; /* usw */ LineTable[5] = PS_DASHDOT; LineTable[6] = PS_DASHDOTDOT; @@ -239,9 +239,9 @@ int WPRINT_Init(void) int WPRINT_NewViewport(GRAPH * graph) { - TEXTMETRIC tm; - tpPrintData pd; - DOCINFO di; + TEXTMETRIC tm; + tpPrintData pd; + DOCINFO di; /* Parameter testen */ if (!graph) { @@ -276,8 +276,8 @@ int WPRINT_NewViewport(GRAPH * graph) pd->LineIndex = 0; /* Viewport-Parameter setzen */ - graph->viewport.height = PrinterHeight; - graph->viewport.width = PrinterWidth; + graph->viewport.height = PrinterHeight; + graph->viewport.width = PrinterWidth; /* Absolut-Parameter setzen */ graph->absolute.xpos = 0; @@ -286,9 +286,9 @@ int WPRINT_NewViewport(GRAPH * graph) graph->absolute.height = PrinterHeight; /* Druckauftrag anmelden */ - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = graph->plotname; - di.lpszOutput = NULL; + di.cbSize = sizeof(DOCINFO); + di.lpszDocName = graph->plotname; + di.lpszOutput = NULL; if (StartDoc(PrinterDC, &di) <= 0) { return 1; } @@ -333,12 +333,14 @@ int WPRINT_Clear(void) } -int WPRINT_DrawLine(int x1, int y1, int x2, int y2) +int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); + tpPrintData pd; - HPEN OldPen; - HPEN NewPen; - int ColIndex; + HPEN OldPen; + HPEN NewPen; + int ColIndex; if (!currentgraph) return 0; pd = pPrintData(currentgraph); @@ -350,12 +352,12 @@ int WPRINT_DrawLine(int x1, int y1, int x2, int y2) ColIndex = 1; MoveToEx(PrinterDC, x1, PrinterHeight - y1, NULL); - NewPen = CreatePen(LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); + NewPen = CreatePen( LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); OldPen = SelectObject(PrinterDC, NewPen); LineTo(PrinterDC, x2, PrinterHeight - y2); OldPen = SelectObject(PrinterDC, OldPen); - DeleteObject(NewPen); - return 0; + DeleteObject( NewPen); + return (0); } diff --git a/src/frontend/wdisp/winprint.h b/src/frontend/wdisp/winprint.h index 8a92992b0..f6d591d02 100644 --- a/src/frontend/wdisp/winprint.h +++ b/src/frontend/wdisp/winprint.h @@ -11,7 +11,7 @@ int WPRINT_Init(void); int WPRINT_NewViewport( GRAPH * graph); int WPRINT_Close(void); int WPRINT_Clear(void); -int WPRINT_DrawLine(int x1, int y1, int x2, int y2); +int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid); int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta); int WPRINT_Text( char * text, int x, int y, int degrees); int WPRINT_DefineColor(int colorid, double red, double green, double blue); diff --git a/src/include/ngspice/ftedev.h b/src/include/ngspice/ftedev.h index b8f3cc12b..f378b5a0a 100644 --- a/src/include/ngspice/ftedev.h +++ b/src/include/ngspice/ftedev.h @@ -18,7 +18,7 @@ typedef int disp_fn_Init_t (void); typedef int disp_fn_NewViewport_t (struct graph *); typedef int disp_fn_Close_t (void); typedef int disp_fn_Clear_t (void); -typedef int disp_fn_DrawLine_t (int x1, int y1, int x2, int y2); +typedef int disp_fn_DrawLine_t (int x1, int y1, int x2, int y2, bool isgrid); typedef int disp_fn_Arc_t (int x0, int y0, int radius, double theta, double delta_theta); typedef int disp_fn_Text_t (char *text, int x, int y, int angle); typedef int disp_fn_DefineColor_t (int colorid, double red, double green, double blue); From d9e3e30c624c99b9b3c8e5232ffac21b29de9679 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Oct 2017 23:18:05 +0200 Subject: [PATCH 17/98] =?UTF-8?q?add=20missing=20=C3=BCarameter=20to=20Dev?= =?UTF-8?q?DrawLine=20for=20X11=20and=20HPGL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/hpgl.c | 4 +++- src/frontend/plotting/x11.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/frontend/hpgl.c b/src/frontend/hpgl.c index 806dd97cb..9b700b1ff 100644 --- a/src/frontend/hpgl.c +++ b/src/frontend/hpgl.c @@ -201,8 +201,10 @@ int GL_Clear(void) } -int GL_DrawLine(int x1, int y1, int x2, int y2) +int +GL_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); /* note: this is not extendible to more than one graph => will have to give NewViewport a writeable graph XXX */ diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 0c63b62fb..319e9dda3 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -1194,7 +1194,7 @@ linear_arc(int x0, int y0, int radius, double theta, double delta_theta) y1 = y2; x2 = x0 + (int)(radius * cos(theta + i*dphi)); y2 = y0 + (int)(radius * sin(theta + i*dphi)); - X11_DrawLine(x1, y1, x2, y2); + X11_DrawLine(x1, y1, x2, y2, FALSE); } } From e5e019c6cec00ecc66dc3ca0dafaf677e5a186cd Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Oct 2017 14:35:19 +0200 Subject: [PATCH 18/98] add gridwidth, xbrushwidth to postscript output --- src/frontend/postsc.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 3ff5ab910..0088a65a4 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -71,7 +71,8 @@ static double scale; /* Used for fine tuning */ static int xtadj; /* text adjustment x */ static int ytadj; /* text adjustment y */ static int hcopygraphid; - +static double linewidth; +static double gridlinewidth; void PS_LinestyleColor(int linestyleid, int colorid); void PS_SelectColor(int colorid); @@ -127,6 +128,19 @@ int PS_Init(void) dispdev->height = 10000; } + /* get linewidth information from spinit */ + if (!cp_getvar("xbrushwidth", CP_REAL, &linewidth)) + linewidth = 0; + if (linewidth < 0) + linewidth = 0; + + /* get linewidth for grid from spinit */ + if (!cp_getvar("gridwidth", CP_REAL, &gridlinewidth)) + gridlinewidth = linewidth; + if (gridlinewidth < 0) + gridlinewidth = 0; + + /* The following side effects have to be considered * when the printer is called by com_hardcopy ! * gr_init: @@ -283,7 +297,6 @@ int PS_Clear(void) int PS_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { - NG_IGNORE(isgrid); /* note: this is not extendible to more than one graph => will have to give NewViewport a writeable graph XXX */ @@ -301,6 +314,10 @@ PS_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) if (x1 != x2 || y1 != y2) { fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff); DEVDEP(currentgraph).linecount += 1; + if(isgrid) + fprintf(plotfile, "%f setlinewidth\n", gridlinewidth); + else + fprintf(plotfile, "%f setlinewidth\n", linewidth); } DEVDEP(currentgraph).lastx = x2; From 90c59ec39e5209a3bb83a47ae55c61b6e0f02489 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Oct 2017 18:34:58 +0200 Subject: [PATCH 19/98] Add function returning the true string length in pixels. May be called from outside of x11.c. --- src/frontend/plotting/x11.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 319e9dda3..7f0b71fda 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -1225,6 +1225,15 @@ Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* fonam return 0; } +/* get the length of an utf-8 string in pixels */ +int +X11_GetLenStr(GRAPH *gr, char* instring) +{ + int wl, wh; + Xget_str_length(instring, &wl, &wh, NULL, DEVDEP(gr).fname, DEVDEP(gr).fsize); + return wl; +} + #else int x11_dummy_symbol; From 2a7fc25f9f22fe79be0f6c96ee54baae121789f8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 8 Oct 2017 12:35:04 +0200 Subject: [PATCH 20/98] tiny update to the short description --- README.utf8 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.utf8 b/README.utf8 index 1def2c79c..ec561aa73 100644 --- a/README.utf8 +++ b/README.utf8 @@ -2,13 +2,14 @@ use utf-8 for encoding of strings, this enables UNICODE international characters sets (of nearly any language) in titles, labels, file and folder names. -Windows uses utf-16 and conversion function between utf-8 +Windows uses utf-16 and conversion functions between utf-8 and utf-16, if access to Windows API functions is needed. A special fopen has been defined. In addition, plot labels on the y axis now are placed -vertically, 90°, by using WWindows API or Linux Xft library. +vertically, 90°, by using the Windows API or the Linux Xft library. -Postscript plotting uses only a UNICODE subset, t.b.d.. +Postscript plotting uses only a UNICODE subset, namely +ISO-8859-1/ISO-8859-15, that allows extended ascii. -Better looking fonts are now used for labelling. +Better looking fonts are now used for labelling the axes. From 4f9040c6b20ecd581705d5e60508a934652d9412 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 9 Dec 2017 12:08:07 +0100 Subject: [PATCH 21/98] Variables xbrushwidth and gridwidth (to be set e.g. in .spiceinit) allow setting separately the linewidths of the graph (xbrushwidth) and the grid (gridwidth). --- README.utf8 | 4 ++++ src/frontend/plotting/gnuplot.c | 17 ++++++++++++----- src/frontend/postsc.c | 4 ++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.utf8 b/README.utf8 index ec561aa73..b7adc0bff 100644 --- a/README.utf8 +++ b/README.utf8 @@ -13,3 +13,7 @@ Postscript plotting uses only a UNICODE subset, namely ISO-8859-1/ISO-8859-15, that allows extended ascii. Better looking fonts are now used for labelling the axes. + +Variables xbrushwidth and gridlinewidth (to be set e.g. in +.spiceinit) allow setting separately the linewidths of the +graph (xbrushwidth) and the grid (gridlinewidth). diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index d07c2f310..1e80798f4 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -56,7 +56,7 @@ void ft_gnuplot(double *xlims, double *ylims, FILE *file, *file_data; struct dvec *v, *scale = NULL; double xval, yval, prev_xval, extrange; - int i, dir, numVecs, linewidth, err, terminal_type; + int i, dir, numVecs, linewidth, gridlinewidth, err, terminal_type; bool xlog, ylog, nogrid, markers; char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text, plotstyle[BSIZE_SP], terminal[BSIZE_SP]; @@ -108,9 +108,16 @@ void ft_gnuplot(double *xlims, double *ylims, } } + /* get linewidth for plotting the graph from .spiceinit */ if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) linewidth = 1; if (linewidth < 1) linewidth = 1; + /* get linewidth for grid from .spiceinit */ + if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = linewidth; + if (gridlinewidth < 1) + gridlinewidth = 1; + if (!cp_getvar("pointstyle", CP_STRING, pointstyle, sizeof(pointstyle))) { markers = FALSE; @@ -188,8 +195,8 @@ void ft_gnuplot(double *xlims, double *ylims, tfree(text); } if (!nogrid) { - if (linewidth > 1) - fprintf(file, "set grid lw %d \n" , linewidth); + if (gridlinewidth > 1) + fprintf(file, "set grid lw %d \n" , gridlinewidth); else fprintf(file, "set grid\n"); } @@ -223,8 +230,8 @@ void ft_gnuplot(double *xlims, double *ylims, fprintf(file, "#set ytics 1\n"); fprintf(file, "#set y2tics 1\n"); - if (linewidth > 1) - fprintf(file, "set border lw %d\n", linewidth); + if (gridlinewidth > 1) + fprintf(file, "set border lw %d\n", gridlinewidth); if (plottype == PLOT_COMB) { strcpy(plotstyle, "boxes"); diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 0088a65a4..3cf3c2eb1 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -129,13 +129,13 @@ int PS_Init(void) } /* get linewidth information from spinit */ - if (!cp_getvar("xbrushwidth", CP_REAL, &linewidth)) + if (!cp_getvar("xbrushwidth", CP_REAL, &linewidth, 0)) linewidth = 0; if (linewidth < 0) linewidth = 0; /* get linewidth for grid from spinit */ - if (!cp_getvar("gridwidth", CP_REAL, &gridlinewidth)) + if (!cp_getvar("gridwidth", CP_REAL, &gridlinewidth, 0)) gridlinewidth = linewidth; if (gridlinewidth < 0) gridlinewidth = 0; From 7849741b7037d2c84f45acf575294f57eae1839b Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 9 Dec 2017 12:51:56 +0100 Subject: [PATCH 22/98] variable gridwidth, not gridlinewidth --- README.utf8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.utf8 b/README.utf8 index b7adc0bff..df29620d3 100644 --- a/README.utf8 +++ b/README.utf8 @@ -14,6 +14,6 @@ ISO-8859-1/ISO-8859-15, that allows extended ascii. Better looking fonts are now used for labelling the axes. -Variables xbrushwidth and gridlinewidth (to be set e.g. in +Variables xbrushwidth and gridwidth (to be set e.g. in .spiceinit) allow setting separately the linewidths of the -graph (xbrushwidth) and the grid (gridlinewidth). +graph (xbrushwidth) and the grid (gridwidth). From 109607a0443e9c937ba0dbd6422806b0afae24d8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 10 Jan 2018 22:17:32 +0100 Subject: [PATCH 23/98] Lengthy op calculations make the Win GUI unresposive. A macro adds a short travel to the GUI fro0m within the matrix ordering and factoring. Time overhead during op is less than 0.5%. --- src/maths/sparse/spfactor.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/maths/sparse/spfactor.c b/src/maths/sparse/spfactor.c index dcfad94ac..337ad2ace 100644 --- a/src/maths/sparse/spfactor.c +++ b/src/maths/sparse/spfactor.c @@ -56,15 +56,24 @@ * Matrix type and macro definitions for the sparse matrix routines. */ #include - #define spINSIDE_SPARSE #include "spconfig.h" #include "ngspice/spmatrix.h" #include "spdefs.h" - - - +#ifdef HAS_WINGUI +extern void SetAnalyse(char *Analyse, int Percent); +/* to increase responsiveness of Windows GUI */ +#define INCRESP \ +do { \ + static int ii = 100; \ + ii--;\ + if (ii == 0) { \ + SetAnalyse("or", 0); \ + ii = 100; \ + } \ +} while(0) +#endif /* * Function declarations @@ -214,6 +223,10 @@ spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold, if (!Matrix->NeedsOrdering) { /* Matrix has been factored before and reordering is not required. */ for (Step = 1; Step <= Size; Step++) { +#ifdef HAS_WINGUI + /* macro to improve responsiveness of Windows GUI */ + INCRESP; +#endif pPivot = Matrix->Diag[Step]; LargestInCol = FindLargestInCol(pPivot->NextInCol); if ((LargestInCol * RelThreshold < ELEMENT_MAG(pPivot))) { @@ -258,6 +271,10 @@ spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold, /* Perform reordering and factorization. */ for (; Step <= Size; Step++) { +#ifdef HAS_WINGUI + /* macro to improve responsiveness of Windows GUI */ + INCRESP; +#endif pPivot = SearchForPivot( Matrix, Step, DiagPivoting ); if (pPivot == NULL) return MatrixIsSingular( Matrix, Step ); ExchangeRowsAndCols( Matrix, pPivot, Step ); From 97065f9507ecf3de87d448abe8f8464ce78cc57a Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Dec 2019 20:38:26 +0100 Subject: [PATCH 24/98] prevent compiler warnings enable short GUI interaction from within spfactor.c --- src/winmain.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index aef846540..c5af4e01a 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -4,6 +4,7 @@ Copyright: Holger Vogt Stand: 09.01.2018 Stand: 20.07.2019 + Stand: 07.12.2019 Modified BSD license */ @@ -181,7 +182,7 @@ SetSource(char *Name) #else wchar_t *NameW; NameW = TMALLOC(wchar_t, 2 * strlen(Name) + 1); - MultiByteToWideChar(CP_UTF8, 0, Name, -1, NameW, 2 * strlen(Name) + 1); + MultiByteToWideChar(CP_UTF8, 0, Name, -1, NameW, 2 * (int)strlen(Name) + 1); SetWindowTextW(hwSource, NameW); tfree(NameW); #endif @@ -210,7 +211,7 @@ SetAnalyse(char *Analyse, /* in: analysis type */ WaitForIdle(); - if ((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) + if (((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) || !strcmp(Analyse, "or")) return; /* get actual time */ @@ -398,7 +399,7 @@ DisplayText(void) #else wchar_t *TWBuffer; TWBuffer = TMALLOC(wchar_t, 2 * strlen(TBuffer) + 1); - if (MultiByteToWideChar(CP_UTF8, 0, TBuffer, -1, TWBuffer, 2 * strlen(TBuffer) + 1) == 0) + if (MultiByteToWideChar(CP_UTF8, 0, TBuffer, -1, TWBuffer, 2 * (int)strlen(TBuffer) + 1) == 0) swprintf(TWBuffer, 2 * strlen(TBuffer), L"UTF-8 to UTF-16 conversion failed with 0x%x\n%hs could not be converted\n", GetLastError(), TBuffer); SetWindowTextW(twText, TWBuffer); tfree(TWBuffer); @@ -1213,7 +1214,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR goto THE_END; { HDC stringDC; - TEXTMETRIC tm; + TEXTMETRICW tm; stringDC = GetDC(swString); if (stringDC) { if (GetTextMetricsW(stringDC, &tm)) From 168210417fff5d416aa670378970bfc2ab8714d5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Dec 2019 20:38:39 +0100 Subject: [PATCH 25/98] small update --- README.utf8 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.utf8 b/README.utf8 index df29620d3..a9e398f58 100644 --- a/README.utf8 +++ b/README.utf8 @@ -17,3 +17,9 @@ Better looking fonts are now used for labelling the axes. Variables xbrushwidth and gridwidth (to be set e.g. in .spiceinit) allow setting separately the linewidths of the graph (xbrushwidth) and the grid (gridwidth). + +Slight modification of the Windows GUI string window to +enhance readability. + +Windows GUI is now more responsive during lengthy op +calculations. From 55c92d63fe7a600cd5f70c94eb84f2fa0f6a7c5e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Dec 2019 20:39:31 +0100 Subject: [PATCH 26/98] setcf -> setcs comments added --- examples/utf-8/стекло/ext-ascii-1.cir | 1 + examples/utf-8/стекло/ext-ascii-2.cir | 6 ++++-- examples/utf-8/стекло/ext-utf8-2.cir | 4 ++-- examples/utf-8/стекло/ext-utf8-cyg2.cir | 10 +++++----- examples/utf-8/стекло/있어요/adder_mos3.cir | 2 +- examples/utf-8/стекло/있어요/ext-utf8-1.cir | 14 +++++++------- .../utf-8/стекло/있어요/ext-utf8-2-있어요.cir | 18 +++++++++--------- examples/utf-8/стекло/있어요/ext-utf8-2.cir | 18 +++++++++--------- examples/utf-8/стекло/있어요/ext-utf8-3.cir | 8 ++++---- examples/utf-8/стекло/있어요/ext-utf8-4.cir | 10 +++++----- examples/utf-8/стекло/있어요/utf-8-inv.cir | 2 +- examples/utf-8/стекло/있어요/utf-8-inv_w.cir | 2 +- 12 files changed, 49 insertions(+), 46 deletions(-) diff --git a/examples/utf-8/стекло/ext-ascii-1.cir b/examples/utf-8/стекло/ext-ascii-1.cir index 72c3b45d8..677d15ff1 100644 --- a/examples/utf-8/стекло/ext-ascii-1.cir +++ b/examples/utf-8/стекло/ext-ascii-1.cir @@ -1,4 +1,5 @@ * test de titre +* file is encoded as ASCII ! .control diff --git a/examples/utf-8/стекло/ext-ascii-2.cir b/examples/utf-8/стекло/ext-ascii-2.cir index f0122d6e3..07a972dff 100644 --- a/examples/utf-8/стекло/ext-ascii-2.cir +++ b/examples/utf-8/стекло/ext-ascii-2.cir @@ -1,4 +1,6 @@ * test de titr +* file is encoded as ASCII ! +* It will fail in utf8 mode. .control set encoding=extended_ascii @@ -6,12 +8,12 @@ set hcopydevtype = postscript set hcopypscolor=1 set hcopyscale=0.5 set color2=rgb:F/0/0 -setcf hcopyfont="Garamond" +setcs hcopyfont="Garamond" set hcopyfontsize=14 let x = vector(5) let y = exp(x) -setcf wfont="Garamond Fett" +setcs wfont="Garamond Fett" set wfont_size=16 plot y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' plot y vs x xlabel 'Labellis X' title 'Titr' diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index abaeb4d40..3ceb60ea7 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -4,12 +4,12 @@ set hcopydevtype = postscript set hcopypscolor=1 set hcopyscale=0.5 set color2=rgb:F/0/0 -setcf hcopyfont=Arial +setcs hcopyfont=Arial set hcopyfontsize=14 let x = vector(5) let y = exp(x) -setcf wfont=Arial +setcs wfont=Arial set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' diff --git a/examples/utf-8/стекло/ext-utf8-cyg2.cir b/examples/utf-8/стекло/ext-utf8-cyg2.cir index f77a036e0..4f48b7e30 100644 --- a/examples/utf-8/стекло/ext-utf8-cyg2.cir +++ b/examples/utf-8/стекло/ext-utf8-cyg2.cir @@ -5,24 +5,24 @@ set hcopydevtype = postscript set hcopypscolor=1 set hcopyscale=0.5 set color2=rgb:F/0/0 -setcf hcopyfont=Arial +setcs hcopyfont=Arial set hcopyfontsize=14 set color0="black" set color1="white" let x = vector(5) let y = exp(x) -setcf xfont="Times New Roman" +setcs xfont="Times New Roman" set xfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' set color0="white" set color1="black" set xfont_size=16 -setcf xfont="Arial" +setcs xfont="Arial" plot y vs x xlabel 'Я могу есть стекло, оно мне не вредит' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Я могу есть стекло, оно мне не вредит' set color0="yellow" set color1="red" set xfont_size=18 -setcf xfont="Noto Sans CJK JP Medium" +setcs xfont="Noto Sans CJK JP Medium" plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog *plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog @@ -33,7 +33,7 @@ echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 echo 私はガラスを食べられます。それは私を傷つけません echo 我能吞下玻璃而不伤身体。 -setcf sourcepath = ( "D:/Spice_general/tests/utf-8/стекло/있어요" ) +setcs sourcepath = ( "D:/Spice_general/tests/utf-8/стекло/있어요" ) source ext-utf8-2.cir gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' diff --git a/examples/utf-8/стекло/있어요/adder_mos3.cir b/examples/utf-8/стекло/있어요/adder_mos3.cir index e84d6a57e..ed90d0d58 100644 --- a/examples/utf-8/стекло/있어요/adder_mos3.cir +++ b/examples/utf-8/стекло/있어요/adder_mos3.cir @@ -65,7 +65,7 @@ X1 1 2 3 4 5 6 7 8 9 10 11 身12 0 Я13 99 FOURBIT .control * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=16 if $?batchmode else diff --git a/examples/utf-8/стекло/있어요/ext-utf8-1.cir b/examples/utf-8/стекло/있어요/ext-utf8-1.cir index 47758fa65..d21144c51 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-1.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-1.cir @@ -2,14 +2,14 @@ .control * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=16 * for LINUX -*setcf xfont='Noto Sans Korean' +*setcs xfont='Noto Sans Korean' let x = vector(5) let y = exp(x) -setcf wfont='Arial' +setcs wfont='Arial' set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 11' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 12 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' @@ -17,15 +17,15 @@ plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 13 plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 14 我能吞下玻璃而不伤身体。' loglog * for CYGWIN -*setcf xfont='Adobe Times' +*setcs xfont='Adobe Times' * for LINUX -setcf xfont='Efont Biwidth' +setcs xfont='Efont Biwidth' plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 15' loglog write D:/Spice_general/tests/utf-8/'стекло'/'있어요'/ext-utf8-1.out x y -setcf sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) -*setcf sourcepath = ( './utf-8/стекло/있어요' ) +setcs sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) +*setcs sourcepath = ( './utf-8/стекло/있어요' ) source ext-utf8-2.cir *source 'D:/Spice_general/tests/utf-8/стекло/있어요/ext-utf8-2.cir' diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir index 00dd8d04d..de061a23c 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir @@ -4,31 +4,31 @@ set hcopydevtype = postscript set hcopypscolor=1 set hcopyscale=0.5 set color2=rgb:F/0/0 -*setcf hcopyfont=Arial +*setcs hcopyfont=Arial * -*setcf hcopyfont='Nimbus Mono-Regular' +*setcs hcopyfont='Nimbus Mono-Regular' * for CYGWIN -setcf hcopyfont='NimbusMonL-Bold' -*setcf hcopyfont='URWGothicL-Book' +setcs hcopyfont='NimbusMonL-Bold' +*setcs hcopyfont='URWGothicL-Book' set hcopyfontsize=14 * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=18 -*setcf xfont='Noto Sans Japanese' +*setcs xfont='Noto Sans Japanese' let x = vector(5) let y = exp(x) -setcf wfont='Arial' +setcs wfont='Arial' set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' 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 *LINUX -*setcf xfont='Noto Sans Korean' +*setcs xfont='Noto Sans Korean' plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog * for CYGWIN -setcf xfont='Times New Roman' +setcs xfont='Times New Roman' 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é Äü @µ€~' diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2.cir b/examples/utf-8/стекло/있어요/ext-utf8-2.cir index 00dd8d04d..de061a23c 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-2.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-2.cir @@ -4,31 +4,31 @@ set hcopydevtype = postscript set hcopypscolor=1 set hcopyscale=0.5 set color2=rgb:F/0/0 -*setcf hcopyfont=Arial +*setcs hcopyfont=Arial * -*setcf hcopyfont='Nimbus Mono-Regular' +*setcs hcopyfont='Nimbus Mono-Regular' * for CYGWIN -setcf hcopyfont='NimbusMonL-Bold' -*setcf hcopyfont='URWGothicL-Book' +setcs hcopyfont='NimbusMonL-Bold' +*setcs hcopyfont='URWGothicL-Book' set hcopyfontsize=14 * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=18 -*setcf xfont='Noto Sans Japanese' +*setcs xfont='Noto Sans Japanese' let x = vector(5) let y = exp(x) -setcf wfont='Arial' +setcs wfont='Arial' set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' 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 *LINUX -*setcf xfont='Noto Sans Korean' +*setcs xfont='Noto Sans Korean' plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog * for CYGWIN -setcf xfont='Times New Roman' +setcs xfont='Times New Roman' 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é Äü @µ€~' diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir index befc033ac..2595dde34 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-3.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -4,12 +4,12 @@ .control * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=18 let x = vector(5) let y = exp(x) -setcf wfont='Arial' +setcs wfont='Arial' set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 11' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 12 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' @@ -17,10 +17,10 @@ plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 13 plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 14 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog * for CYGWIN -setcf xfont='Times New Roman' +setcs xfont='Times New Roman' plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 15' loglog -setcf sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) +setcs sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) source ext-utf8-4.cir * better to put ouput into single quotes diff --git a/examples/utf-8/стекло/있어요/ext-utf8-4.cir b/examples/utf-8/стекло/있어요/ext-utf8-4.cir index db4c24e7c..e9b4f49e3 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-4.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-4.cir @@ -4,25 +4,25 @@ set hcopydevtype = postscript set hcopypscolor=1 set hcopyscale=0.5 set color2=rgb:F/0/0 -*setcf hcopyfont=Arial +*setcs hcopyfont=Arial * for CYGWIN -setcf hcopyfont='NimbusMono-Regular' +setcs hcopyfont='NimbusMono-Regular' set hcopyfontsize=14 * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=16 let x = vector(5) let y = exp(x) -setcf wfont='Arial' +setcs wfont='Arial' set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' 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 * for CYGWIN -setcf xfont='Times New Roman' +setcs xfont='Times New Roman' 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é Äü @µ€~' diff --git a/examples/utf-8/стекло/있어요/utf-8-inv.cir b/examples/utf-8/стекло/있어요/utf-8-inv.cir index 8853bd3c1..f11d9efa9 100644 --- a/examples/utf-8/стекло/있어요/utf-8-inv.cir +++ b/examples/utf-8/стекло/있어요/utf-8-inv.cir @@ -33,7 +33,7 @@ VIN1B は2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) .control * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=16 if $?batchmode else diff --git a/examples/utf-8/стекло/있어요/utf-8-inv_w.cir b/examples/utf-8/стекло/있어요/utf-8-inv_w.cir index adeccc347..1a0a1c588 100644 --- a/examples/utf-8/стекло/있어요/utf-8-inv_w.cir +++ b/examples/utf-8/стекло/있어요/utf-8-inv_w.cir @@ -33,7 +33,7 @@ VIN1B は2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) .control * for CYGWIN -setcf xfont='Noto Sans CJK JP Medium' +setcs xfont='Noto Sans CJK JP Medium' set xfont_size=16 if $?batchmode From 6a7e9db1e18c35c555b6aa3f094d58182c7020c6 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 10 Dec 2019 00:34:47 +0100 Subject: [PATCH 27/98] add some plots --- examples/utf-8/стекло/ext-utf8-2.cir | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index 3ceb60ea7..97421b457 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -11,16 +11,23 @@ let x = vector(5) let y = exp(x) setcs wfont=Arial set wfont_size=18 +setcs xfont='Noto Sans Chinese' +set gridwidth=4 +*set xbrushwidth=4 +*set xfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog *plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' *hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' *shell Start /B plot_5.ps echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 +* the next one requires: export LC_CTYPE ="de_DE.UTF-8" gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' *quit From c000b2042a6a7c14524a1cd2eba95b9e4fc52866 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 10 Dec 2019 00:36:34 +0100 Subject: [PATCH 28/98] allow independent linewidth and gridwidth settings from within the .control section --- src/frontend/plotting/gnuplot.c | 5 +++-- src/frontend/plotting/x11.c | 4 ++-- src/frontend/wdisp/windisp.c | 14 +++++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index 1e80798f4..9672af6cd 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -111,10 +111,11 @@ void ft_gnuplot(double *xlims, double *ylims, /* get linewidth for plotting the graph from .spiceinit */ if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) linewidth = 1; - if (linewidth < 1) linewidth = 1; + if (linewidth < 1) + linewidth = 1; /* get linewidth for grid from .spiceinit */ if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) - gridlinewidth = linewidth; + gridlinewidth = 1; if (gridlinewidth < 1) gridlinewidth = 1; diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 7f0b71fda..b60ef09f4 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -152,7 +152,7 @@ X11_Init(void) return (1); } - if (cp_getvar("old_x11", CP_BOOL, NULL)) + if (cp_getvar("old_x11", CP_BOOL, NULL, 0)) old_x11 = TRUE; # ifdef DEBUG @@ -478,7 +478,7 @@ X11_NewViewport(GRAPH *graph) } /* font size */ - if (!cp_getvar("xfont_size", CP_NUM, &xfont_size)) + if (!cp_getvar("xfont_size", CP_NUM, &xfont_size, 0)) xfont_size = 16; if(old_x11) { diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 6f7f99d9b..f6b2a4078 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -3,7 +3,7 @@ * Wolfgang Muees 27.10.97 * Holger Vogt 07.12.01 * Holger Vogt 05.12.07 - * Holger Vogt 01.11.18 + * Holger Vogt 01.11.18 */ #include "ngspice/ngspice.h" @@ -823,6 +823,18 @@ int WIN_NewViewport(GRAPH *graph) graph->absolute.width = wd->Area.right; graph->absolute.height = wd->Area.bottom; + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) + linewidth = 0; + if (linewidth < 0) + linewidth = 0; + + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = 0; + if (gridlinewidth < 0) + gridlinewidth = 0; + /* wait until the window is really there */ WaitForIdle(); From 67b84f3d2dc4e20464adf40955bca02413c49bb5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 10 Dec 2019 00:44:01 +0100 Subject: [PATCH 29/98] add local linewidth change for plot and gnuplot commands --- examples/utf-8/стекло/ext-utf8-2.cir | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index 97421b457..4c565cf58 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -12,23 +12,31 @@ let y = exp(x) setcs wfont=Arial set wfont_size=18 setcs xfont='Noto Sans Chinese' -set gridwidth=4 -*set xbrushwidth=4 *set xfont_size=18 + +set gridwidth=4 +set xbrushwidth=1 + plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +set gridwidth=1 +set xbrushwidth=4 + plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog *plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + *hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' *shell Start /B plot_5.ps echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 echo 私はガラスを食べられます。それは私を傷つけません echo 我能吞下玻璃而不伤身体 -* the next one requires: export LC_CTYPE ="de_DE.UTF-8" -gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' - *quit .endc From cb4eeb44eed175e6d9e10e9acc8a9bb523ccc1ed Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 21 Dec 2019 12:35:18 +0100 Subject: [PATCH 30/98] re-organize PS color selection Improve settings for PS image Improve error messages --- examples/utf-8/стекло/ext-utf8-2.cir | 14 +++-- src/frontend/postsc.c | 86 +++++++++++++++++----------- 2 files changed, 63 insertions(+), 37 deletions(-) diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index 4c565cf58..60359db64 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -1,11 +1,12 @@ * test de titré .control set hcopydevtype = postscript -set hcopypscolor=1 -set hcopyscale=0.5 +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 set color2=rgb:F/0/0 setcs hcopyfont=Arial -set hcopyfontsize=14 +set hcopyfontsize=18 let x = vector(5) let y = exp(x) @@ -17,6 +18,8 @@ setcs xfont='Noto Sans Chinese' set gridwidth=4 set xbrushwidth=1 +hardcopy + plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" @@ -32,8 +35,9 @@ plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べ * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' -*shell Start /B plot_5.ps +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +shell Start /B plot_5.ps + echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 echo 私はガラスを食べられます。それは私を傷つけません echo 我能吞下玻璃而不伤身体 diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 3cf3c2eb1..1cb23cf89 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -40,6 +40,36 @@ Author: 1988 Jeffrey M. Hsu #define FONTWIDTH 6 /* printer default fontwidth */ #define FONTHEIGHT 14 /* printer default fontheight */ + +typedef struct { + int red, green, blue; +} COLOR; + +/* duplicated colors from src/frontend/plotting/x11.c in rgb-style */ +static const COLOR colors[] = {{ 0, 0, 0}, /*0: black */ + {255, 255, 255}, /*1: white */ + {255, 0, 0}, /*2: red */ + { 0, 0, 255}, /*3: blue */ + {255, 165, 0}, /*4: orange */ + { 0, 255, 0}, /*5: green */ + {255, 192, 203}, /*6: pink */ + {165, 42, 42}, /*7: brown */ + {240, 230, 140}, /*8: khaki */ + {221, 160, 221}, /*9: plum */ + {218, 112, 214}, /*10: orchid */ + {238, 130, 238}, /*11: violet */ + {176, 48, 96}, /*12: maroon */ + { 64, 224, 208}, /*13: turqoise */ + {160, 82, 45}, /*14: sienna */ + {255, 127, 80}, /*15: coral */ + { 0, 255, 255}, /*16: cyan */ + {255, 0, 255}, /*17: magenta */ + {255, 215, 0}, /*18: gold */ + {255, 255, 0}, /*19: yello */ + { 96, 96, 96}, /*20: gray for smith grid */ + {150, 150, 150}, /*21: gray for smith grid */ + {128, 128, 128}}; /*22: gray for normal grid */ + typedef struct { int lastlinestyle, lastcolor; /* initial invalid value */ int lastx, lasty, linecount; @@ -73,6 +103,7 @@ static int ytadj; /* text adjustment y */ static int hcopygraphid; static double linewidth; static double gridlinewidth; +static int maxcolor = 2; void PS_LinestyleColor(int linestyleid, int colorid); void PS_SelectColor(int colorid); @@ -85,6 +116,8 @@ int PS_Init(void) { char pswidth[30], psheight[30]; + maxcolor = NUMELEMS(colors); + if (!cp_getvar("hcopyscale", CP_STRING, psscale, sizeof(psscale))) { scale = 1.0; } else { @@ -100,12 +133,26 @@ int PS_Init(void) dispdev->numcolors = 2; } else { - /* get backgroung color and set plot to color */ + /* get text color and set plot to color */ colorflag = 1; - dispdev->numcolors = 21; /* don't know what the maximum should be */ + dispdev->numcolors = maxcolor; cp_getvar("hcopypstxcolor", CP_NUM, &settxcolor, 0); } + if (settxcolor > maxcolor || settxcolor < 0) { + fprintf(stderr, "Bad PS text color selection %d\n", settxcolor); + fprintf(stderr, " Maximum for hcopypstxcolor is %d\n", maxcolor - 1); + colorflag = 0; + dispdev->numcolors = 2; + } + + if (setbgcolor > maxcolor || setbgcolor < 0) { + fprintf(stderr, "Bad PS background color selection %d\n", setbgcolor); + fprintf(stderr, " Maximum for hcopypscolor is %d\n", maxcolor - 1); + fprintf(stderr, " Set to 1 (white)\n"); + setbgcolor = 1; + } + /* plot size */ if (!cp_getvar("hcopywidth", CP_STRING, pswidth, sizeof( pswidth))) { dispdev->width = (int)(7.75 * 72.0 * scale); /* (8 1/2 - 3/4) * 72 */ @@ -163,7 +210,7 @@ int PS_Init(void) } else { sscanf(psfontsize, "%d", &fontsize); - if ((fontsize < 10) || (fontsize > 14)) + if ((fontsize < 10) || (fontsize > 18)) fontsize = 10; fontwidth = (int)(0.5 + 0.6 * fontsize); fontheight = (int)(2.5 + 1.2 * fontsize); @@ -214,13 +261,13 @@ int PS_NewViewport(GRAPH *graph) xoff = (int)(scale * XOFF); yoff = (int)(scale * YOFF); - x1 = (int)(0.75 * 72); + x1 = (int) (0.5 * 72 - fontheight); y1 = x1; - x2 = (int)(graph->absolute.width + .75 * 72); + x2 = (int)(graph->absolute.width + .5 * 72); y2 = (int)(graph->absolute.height + .75 * 72); /* start file off with a % */ fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n"); - fprintf(plotfile, "%%%%Creator: nutmeg\n"); + fprintf(plotfile, "%%%%Creator: ngspice\n"); fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n", x1, y1, x2, y2); /* Re-encoding to allow 'extended asccii' @@ -432,31 +479,6 @@ void PS_SelectColor(int colorid) /* should be replaced by PS_DefineCol char rgb[30], s_red[30] = "0x", s_green[30] = "0x", s_blue[30] = "0x"; int red = 0, green = 0, blue = 0, maxval = 1; int i; - typedef struct { int red, green, blue;} COLOR; - /* duplicated colors from src/frontend/plotting/x11.c in rgb-style */ - const COLOR colors[] = {{ 0, 0, 0}, /*0: black */ - {255, 255, 255}, /*1: white */ - {255, 0, 0}, /*2: red */ - { 0, 0, 255}, /*3: blue */ - {255, 165, 0}, /*4: orange */ - { 0, 255, 0}, /*5: green */ - {255, 192, 203}, /*6: pink */ - {165, 42, 42}, /*7: brown */ - {240, 230, 140}, /*8: khaki */ - {221, 160, 221}, /*9: plum */ - {218, 112, 214}, /*10: orchid */ - {238, 130, 238}, /*11: violet */ - {176, 48, 96}, /*12: maroon */ - { 64, 224, 208}, /*13: turqoise */ - {160, 82, 45}, /*14: sienna */ - {255, 127, 80}, /*15: coral */ - { 0, 255, 255}, /*16: cyan */ - {255, 0, 255}, /*17: magenta */ - /*{255, 215, 0}, 18: gold */ - { 96, 96, 96}, /*18: gray for smith grid */ - /*{255, 255, 0}, 19: yello */ - {150, 150, 150}, /*19: gray for smith grid */ - {128, 128, 128}}; /*20: gray for normal grid */ /* Extract the rgbcolor, format is: "rgb://" */ sprintf(colorN, "color%d", colorid); @@ -478,7 +500,7 @@ void PS_SelectColor(int colorid) /* should be replaced by PS_DefineCol strcpy(pscolor, colorstring); } } - if (colorid < 0 || colorid > 20) { + if (colorid < 0 || colorid >= maxcolor) { internalerror("bad colorid inside PS_SelectColor"); } else if (maxval == 1) { /* colorN is not an rgbstring, use default color */ sprintf(colorstring, "%1.3f %1.3f %1.3f", colors[colorid].red/255.0, From 1c1c53434ba620c51a5ed74841b7df13017e85bb Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 21 Dec 2019 13:02:38 +0100 Subject: [PATCH 31/98] prevent crash if 'hardcopy' is given without parameters --- src/frontend/com_hardcopy.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c index 39aa0baed..881ab7d23 100644 --- a/src/frontend/com_hardcopy.c +++ b/src/frontend/com_hardcopy.c @@ -73,10 +73,18 @@ void com_hardcopy(wordlist *wl) if (!wl && hc_button) { char *psfname; GRAPH *tempgraph; - if (DevSwitch(devtype)) { + /* initialze PS by calling PS_Init() */ + if (DevSwitch(devtype)) + return; + if (currentgraph) + tempgraph = CopyGraph(currentgraph); + else { + fprintf(stderr, + "No parameters for hardcopy command, not previous plot:\n"); + fprintf(stderr, " Command hardcopy cannot be executed\n "); return; } - tempgraph = CopyGraph(currentgraph); + /* change .tmp to .ps */ psfname = strchr(fname, '.'); if (psfname) { @@ -150,7 +158,7 @@ void com_hardcopy(wordlist *wl) PushGraphContext(currentgraph); if (!foundit) { - if (!wl) { + if (!wl && cp_getvar("interactive", CP_BOOL, NULL, 0)) { char *buf2; outmenuprompt("which variable ? "); buf2 = prompt(cp_in); From 4383d4839b7acb4920f65635eeb0a6226ed9f177 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 21 Dec 2019 23:55:58 +0100 Subject: [PATCH 32/98] Re-sort wide char variable definitions. add utf-8 ... utf-16 conversion. Strings in history buffer shall remain utf-8. History buffering is not yet working. --- src/winmain.c | 63 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index c5af4e01a..2263c53e9 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -78,36 +78,39 @@ HWND hwAnalyse; /* analysis window */ HWND hwQuitButton; /* Pause button */ static int nReturnCode = 0; /* WinMain return value */ static int nShowState; /* Display mode of main window */ +#ifdef EXT_ASC static WNDCLASS hwMainClass; /* Class definition for the main window */ -static WNDCLASSW hwMainClassW; /* Class definition for the main window */ static LPCTSTR hwClassName = "SPICE_TEXT_WND";/* Class name of the main window */ static LPCTSTR hwWindowName = PACKAGE_STRING; /* main window displayed name */ -static LPCWSTR hwClassNameW = L"SPICE_TEXT_WND";/* Class name of the main window */ -static LPCWSTR hwWindowNameW = L"ngspice 26"; /* main window displayed name */ static WNDCLASS twTextClass; /* Class definition for the text box */ -static WNDCLASSW twTextClassW; /* Class definition for the text box */ static LPCTSTR twClassName = "SPICE_TEXT_BOX"; /* Class name for the text box */ static LPCTSTR twWindowName = "TextOut"; /* text box name */ -static LPCWSTR twClassNameW = L"SPICE_TEXT_BOX"; /* Class name for the text box */ -static LPCWSTR twWindowNameW = L"TextOut"; /* text box name */ -static size_t TBufEnd = 0; /* Pointer to \0 */ -static char TBuffer[TBufSize + 1]; /* Text buffer */ -static SBufLine SBuffer; /* Input buffer */ static WNDCLASS swStringClass; /* Class definition of string window */ static LPCTSTR swClassName = "SPICE_STR_IN"; /* Class name of text input */ static LPCTSTR swWindowName = "StringIn"; /* Window name */ -static WNDCLASSW swStringClassW; /* Class definition of string window */ -static LPCWSTR swClassNameW = L"SPICE_STR_IN"; /* Class name of text input */ -static LPCWSTR swWindowNameW = L"StringIn"; /* Window name */ -static char CRLF[] = {CR, LF, SE}; /* CR/LF */ static WNDCLASS hwElementClass; /* Class definition of status displays */ static LPCTSTR hwElementClassName = "ElementClass"; static LPCTSTR hwSourceWindowName = "SourceDisplay"; static LPCTSTR hwAnalyseWindowName = "AnalyseDisplay"; +#else +static WNDCLASSW hwMainClassW; /* Class definition for the main window */ +static LPCWSTR hwClassNameW = L"SPICE_TEXT_WND";/* Class name of the main window */ +static LPCWSTR hwWindowNameW = L"ngspice 26"; /* main window displayed name */ +static WNDCLASSW twTextClassW; /* Class definition for the text box */ +static LPCWSTR twClassNameW = L"SPICE_TEXT_BOX"; /* Class name for the text box */ +static LPCWSTR twWindowNameW = L"TextOut"; /* text box name */ +static WNDCLASSW swStringClassW; /* Class definition of string window */ +static LPCWSTR swClassNameW = L"SPICE_STR_IN"; /* Class name of text input */ +static LPCWSTR swWindowNameW = L"StringIn"; /* Window name */ static WNDCLASSW hwElementClassW; /* Class definition of status displays */ static LPCWSTR hwElementClassNameW = L"ElementClass"; static LPCWSTR hwSourceWindowNameW = L"SourceDisplay"; static LPCWSTR hwAnalyseWindowNameW = L"AnalyseDisplay"; +#endif +static size_t TBufEnd = 0; /* Pointer to \0 */ +static char TBuffer[TBufSize + 1]; /* Text buffer */ +static SBufLine SBuffer; /* Input buffer */ +static char CRLF[] = {CR, LF, SE}; /* CR/LF */ static int RowHeight = 16; /* Height of line of text */ static int LineHeight = 25; /* Height of input line */ static int VisibleRows = 10; /* Number of visible lines in text window */ @@ -122,12 +125,8 @@ extern FILE *flogp; /* definition see xmain.c, stdout redirected to file */ extern void cp_doquit(void); - - static struct History_info *init_history(void); - - // ---------------------------------------------------------- // Warte, bis keine Messages mehr zu bearbeiten sind @@ -563,16 +562,33 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) switch (uMsg) { case WM_CREATE: /* Get access to history information */ +#ifdef EXT_ASC pp_hi = (struct History_info **) ((LPCREATESTRUCT) lParam)->lpCreateParams; +#else + pp_hi = (struct History_info **) + ((LPCREATESTRUCTW) lParam)->lpCreateParams; +#endif break; case WM_KEYDOWN: { const UINT i = (UINT) wParam; if ((i == VK_UP) || (i == VK_DOWN)) { /* Set old text to new */ +#ifdef EXT_ASC SetWindowText(hwnd, (i == VK_UP) ? history_get_prev(*pp_hi, NULL) : history_get_next(*pp_hi, NULL)); +#else + const char *newtext = (i == VK_UP) ? + history_get_prev(*pp_hi, NULL) : + history_get_next(*pp_hi, NULL); + wchar_t *newtextW; + newtextW = TMALLOC(wchar_t, 2 * strlen(newtext) + 1); + MultiByteToWideChar( + CP_UTF8, 0, newtext, -1, newtextW, 2 * (int) strlen(newtext) + 1); + SetWindowTextW(hwSource, newtextW); + tfree(newtextW); +#endif /* Put cursor to end of line */ CallWindowProc(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam); return 0; @@ -592,8 +608,17 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) * buffer for writing the string + NULL. The NULL will be * overwritten by the strcpy below, so it should not be * counted in the size needed for the CRLF string. */ +#ifdef EXT_ASC const int n_char_returned = GetWindowText( hwnd, SBuffer, sizeof SBuffer - (sizeof CRLF - 1)); +#else + wchar_t *WBuffer = TMALLOC(wchar_t, sizeof(SBuffer)); + const int n_char_returned = GetWindowTextW( + hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1)); + WideCharToMultiByte(CP_UTF8, 0, WBuffer, -1, SBuffer, + 1023, NULL, NULL); + tfree(WBuffer); +#endif unsigned int n_char_prev_cmd; /* Add the command to the history if it is different from the @@ -1209,7 +1234,9 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR } #else swString = CreateWindowExW(WS_EX_NOPARENTNOTIFY, swClassNameW, swWindowNameW, - ES_LEFT | WS_CHILD | WS_BORDER, 20, 20, 300, 100, hwMain, NULL, hInst, NULL); + ES_LEFT | WS_CHILD | WS_BORDER | + ES_AUTOHSCROLL, /* Allow text to scroll */ + 20, 20, 300, 100, hwMain, NULL, hInst, &p_hi); if (!swString) goto THE_END; { From 1e08fd699330c6886da086b9a88ed60b9fd1d968 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 15:53:27 +0100 Subject: [PATCH 33/98] increase buffer size, send text to string window, retrieve the correct number of byte after utf-8 conversion. Answering to a promt (e.g. after command 'hardcopy') does not yet do. --- src/winmain.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index 2263c53e9..43ff6f555 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -42,7 +42,7 @@ #define LF 10 // Line Feed #define SE 0 // String termination #define BorderSize 8 // Umrandung des Stringfeldes -#define SBufSize 100 // Groesze des Stringbuffers +#define SBufSize 300 // Groesze des Stringbuffers #define IOBufSize 16348 // Groesze des printf-Buffers #define HIST_SIZE 20 /* Max # commands held in history */ #define N_BYTE_HIST_BUF 512 /* Initial size of history buffer in bytes */ @@ -578,6 +578,8 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) SetWindowText(hwnd, (i == VK_UP) ? history_get_prev(*pp_hi, NULL) : history_get_next(*pp_hi, NULL)); + /* Put cursor to end of line */ + CallWindowProc(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam); #else const char *newtext = (i == VK_UP) ? history_get_prev(*pp_hi, NULL) : @@ -586,11 +588,11 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) newtextW = TMALLOC(wchar_t, 2 * strlen(newtext) + 1); MultiByteToWideChar( CP_UTF8, 0, newtext, -1, newtextW, 2 * (int) strlen(newtext) + 1); - SetWindowTextW(hwSource, newtextW); + SetWindowTextW(swString, newtextW); tfree(newtextW); -#endif /* Put cursor to end of line */ - CallWindowProc(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam); + CallWindowProcW(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam); +#endif return 0; } if (i == VK_ESCAPE) { @@ -613,10 +615,11 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) hwnd, SBuffer, sizeof SBuffer - (sizeof CRLF - 1)); #else wchar_t *WBuffer = TMALLOC(wchar_t, sizeof(SBuffer)); - const int n_char_returned = GetWindowTextW( - hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1)); - WideCharToMultiByte(CP_UTF8, 0, WBuffer, -1, SBuffer, - 1023, NULL, NULL); + /* for utf-8 the number of characters is not the number of bytes returned */ + GetWindowTextW(hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1)); + /* retrive here the number of bytes returned */ + const int n_char_returned = WideCharToMultiByte(CP_UTF8, 0, WBuffer, + -1, SBuffer, sizeof SBuffer - 1, NULL, NULL); tfree(WBuffer); #endif unsigned int n_char_prev_cmd; @@ -638,7 +641,6 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) history_reset_pos(*pp_hi); } - strcpy(SBuffer + n_char_returned, CRLF); ClearInput(); return 0; From 68f95d4407064f69e68dc1108d2460265bdc8ef7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 22:18:37 +0100 Subject: [PATCH 34/98] command hardcopy changes font, check is necessary --- examples/utf-8/стекло/ext-utf8-2.cir | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index 60359db64..fbeb07417 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -35,6 +35,10 @@ plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べ * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' shell Start /B plot_5.ps From 52a65f0aac6540fd14c2d24ae94428c00dee00d0 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 22:21:27 +0100 Subject: [PATCH 35/98] return NULL upon NULL input --- src/misc/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/misc/util.c b/src/misc/util.c index a4c14ddf3..0cd320cbb 100644 --- a/src/misc/util.c +++ b/src/misc/util.c @@ -258,6 +258,7 @@ ngdirname(const char *name) #endif +/* Replacement for fopen, when using wide chars (utf-16) */ #ifndef EXT_ASC #if defined(__MINGW__) || defined(_MSC_VER) #undef BOOLEAN @@ -265,10 +266,11 @@ ngdirname(const char *name) FILE * newfopen(char *fn, char* md) { + if (fn == NULL) + return NULL; wchar_t wfn[BSIZE_SP]; wchar_t wmd[16]; MultiByteToWideChar(CP_UTF8, 0, md, -1, wmd, 15); - MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, BSIZE_SP - 1); if (MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, BSIZE_SP - 1) == 0) { fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n", GetLastError()); fprintf(stderr, "%s could not be converted\n", fn); From 93eb6d19548cb74b472d2c5aa2f0bb6b7605e241 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 22:22:19 +0100 Subject: [PATCH 36/98] utf-8 string length determined by strlen --- src/winmain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index 43ff6f555..5d98ae2be 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -617,9 +617,10 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) wchar_t *WBuffer = TMALLOC(wchar_t, sizeof(SBuffer)); /* for utf-8 the number of characters is not the number of bytes returned */ GetWindowTextW(hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1)); - /* retrive here the number of bytes returned */ - const int n_char_returned = WideCharToMultiByte(CP_UTF8, 0, WBuffer, + WideCharToMultiByte(CP_UTF8, 0, WBuffer, -1, SBuffer, sizeof SBuffer - 1, NULL, NULL); + /* retrive here the number of bytes returned */ + const int n_char_returned = (int)strlen(SBuffer); tfree(WBuffer); #endif unsigned int n_char_prev_cmd; From 85177fdaa304b10321c4b2028589a2d1038d44dd Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 22:22:44 +0100 Subject: [PATCH 37/98] Reset DevSwitch before returning --- src/frontend/com_hardcopy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c index 881ab7d23..9a2d22e0e 100644 --- a/src/frontend/com_hardcopy.c +++ b/src/frontend/com_hardcopy.c @@ -82,6 +82,7 @@ void com_hardcopy(wordlist *wl) fprintf(stderr, "No parameters for hardcopy command, not previous plot:\n"); fprintf(stderr, " Command hardcopy cannot be executed\n "); + DevSwitch(NULL); return; } From f1e08d7d323c0aab3986dce9840767065fcd35b9 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 23:01:44 +0100 Subject: [PATCH 38/98] add to the source window after 'source' command --- src/frontend/inp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 729102dc9..ba1668117 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -79,6 +79,11 @@ extern bool ft_batchmode; extern void exec_controls(wordlist *controls); #endif +/* display the source file name in the source window */ +#ifdef HAS_WINGUI +extern void SetSource(char *Name); +#endif + /* structure used to save expression parse trees for .model and * device instance lines */ @@ -1605,6 +1610,10 @@ com_source(wordlist *wl) if (ft_nutmeg || substring(INITSTR, owl->wl_word) || substring(ALT_INITSTR, owl->wl_word)) inp_spsource(fp, TRUE, tempfile ? NULL : wl->wl_word, FALSE); else { +#ifdef HAS_WINGUI + /* set the source window */ + SetSource(wl->wl_word); +#endif /* Save path name for use in XSPICE fopen_with_path() */ if (Infile_Path) tfree(Infile_Path); From 405807bb0860b598c01d0fde90db1abd746e8ac5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 23:02:29 +0100 Subject: [PATCH 39/98] Don't call DestroyGraph if graf id is 0 --- src/frontend/postsc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 1cb23cf89..a85745843 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -141,7 +141,7 @@ int PS_Init(void) if (settxcolor > maxcolor || settxcolor < 0) { fprintf(stderr, "Bad PS text color selection %d\n", settxcolor); - fprintf(stderr, " Maximum for hcopypstxcolor is %d\n", maxcolor - 1); + fprintf(stderr, " Maximum for hcopypstxcolor is %d\n\n", maxcolor - 1); colorflag = 0; dispdev->numcolors = 2; } @@ -149,7 +149,7 @@ int PS_Init(void) if (setbgcolor > maxcolor || setbgcolor < 0) { fprintf(stderr, "Bad PS background color selection %d\n", setbgcolor); fprintf(stderr, " Maximum for hcopypscolor is %d\n", maxcolor - 1); - fprintf(stderr, " Set to 1 (white)\n"); + fprintf(stderr, " Set to 1 (white)\n\n"); setbgcolor = 1; } @@ -327,7 +327,8 @@ int PS_Close(void) * and reset currentgraph to graphid 1, if possible */ if (!screenflag) { - DestroyGraph(hcopygraphid); + if (hcopygraphid > 0) + DestroyGraph(hcopygraphid); currentgraph = FindGraph(1); } return 0; From d7400749ca9a33adeec6f408185a23a62e84e2b9 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 22 Dec 2019 23:03:54 +0100 Subject: [PATCH 40/98] add empty line after error message --- src/frontend/com_hardcopy.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c index 9a2d22e0e..2a7cba1a8 100644 --- a/src/frontend/com_hardcopy.c +++ b/src/frontend/com_hardcopy.c @@ -66,9 +66,6 @@ void com_hardcopy(wordlist *wl) /* enable screen plot selection for these display types */ foundit = 0; - - // PushGraphContext(currentgraph); - #ifdef HAS_WINGUI if (!wl && hc_button) { char *psfname; @@ -81,7 +78,7 @@ void com_hardcopy(wordlist *wl) else { fprintf(stderr, "No parameters for hardcopy command, not previous plot:\n"); - fprintf(stderr, " Command hardcopy cannot be executed\n "); + fprintf(stderr, " Command hardcopy cannot be executed\n\n"); DevSwitch(NULL); return; } From e702d5f55c269160a3ba999eacaab3f112d52530 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 28 Dec 2019 10:35:28 +0100 Subject: [PATCH 41/98] improve on memory leaks (not yet completely satisfying) --- src/frontend/plotting/plotit.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index 95fb45207..2d3d1bf5c 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -287,7 +287,6 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) int i, y_type, xt; wordlist *wwl; char *nxlabel = NULL, *nylabel = NULL, *ntitle = NULL; - double tstep, tstart, tstop, ttime; /* Save start of vectors on entry for cleaning up junk left behind From 33647d14ef0640dc8a1d85bf64ccd8c11e4d940e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 28 Dec 2019 10:39:04 +0100 Subject: [PATCH 42/98] Select suitable default text color --- src/frontend/postsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index a85745843..f0eaad0c0 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -96,7 +96,7 @@ static int fontheight = FONTHEIGHT; static int screenflag = 0; static int colorflag = 0; static int setbgcolor = 0; -static int settxcolor = -1; +static int settxcolor = 1; static double scale; /* Used for fine tuning */ static int xtadj; /* text adjustment x */ static int ytadj; /* text adjustment y */ From 5aa7ab6f4bd104c900c75beaf7596e92a4afb2b1 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 28 Dec 2019 10:49:01 +0100 Subject: [PATCH 43/98] Prepare font selection and rotation only once per graph in func X11_DefineXft(). Only 0 and 90 degree are supported. --- src/frontend/plotting/x11.c | 104 +++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index b60ef09f4..5e5ff6f6f 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -76,6 +76,11 @@ typedef struct x11info { char bgcolor[16]; char fname[BSIZE_SP]; int fsize; + XftFont *font0; + XftFont *font90; + XftDraw* draw; + XftColor color; + Colormap cmap; } X11devdep; #define DEVDEP(g) (*((X11devdep *) (g)->devdep)) @@ -112,6 +117,7 @@ static void linear_arc(int x0, int y0, int radius, double theta, double delta_th static void slopelocation(GRAPH *graph, int x0, int y0); static void zoomin(GRAPH *graph); static int Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* name, int fsize); +static int X11_DefineXft(GRAPH *graph); //XtEventHandler static void handlekeypressed(Widget w, XtPointer clientdata, XEvent *ev, Boolean *continue_dispatch); @@ -529,6 +535,7 @@ X11_NewViewport(GRAPH *graph) cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); + X11_DefineXft(graph); /* WM_DELETE_WINDOW protocol */ atom_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); @@ -619,46 +626,66 @@ X11_Text(char *text, int x, int y, int angle) return 0; } - /* new font selection with rotation */ - XftPattern *new_pat = XftPatternCreate(); // the pattern we will use for rotating - XftPatternAddString(new_pat, XFT_FAMILY, DEVDEP(currentgraph).fname); - XftPatternAddDouble (new_pat, XFT_PIXEL_SIZE, (double)DEVDEP(currentgraph).fsize); - - if(angle != 0){ - XftMatrix m; - XftMatrixInit(&m); - XftMatrixRotate(&m,cos(M_PI*angle/180.),sin(M_PI*angle/180.)); - XftPatternAddMatrix (new_pat, XFT_MATRIX,&m); - } - - XftResult rot_result; - XftPattern *rot_pat = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ - XftFont *new_font = XftFontOpenPattern(display, rot_pat); - XftPatternDestroy(new_pat); - - /* calculate and add offset, if ylabel with angle 90 */ - if (angle == 90) { - Xget_str_length(text, &wlen, &wheight, new_font, NULL, 0); - } - - Colormap cmap = DefaultColormap(display, 0); - XftColor color; - XftColorAllocName(display, DefaultVisual(display, 0), cmap, DEVDEP(currentgraph).txtcolor, &color); - XftDraw* draw = XftDrawCreate( - display, DEVDEP(currentgraph).window, DefaultVisual(display, 0), cmap - ); /* Draw text */ - XftDrawStringUtf8( - draw, &color, new_font, - x + (int)(1.5 * wlen), currentgraph->absolute.height - y + (int)(0.5 * wheight), (FcChar8*)text, strlen(text) - ); - XftFontClose( display, new_font); - XftDrawDestroy(draw); - XftColorFree(display, DefaultVisual(display, 0), cmap, &color); + if(angle == 0) { + XftDrawStringUtf8( + DEVDEP(currentgraph).draw, &DEVDEP(currentgraph).color, DEVDEP(currentgraph).font0, + x, currentgraph->absolute.height - y, (FcChar8*)text, strlen(text)); + } + else if (angle == 90) { + int wlen, wheight; + /* calculate and add offset, if ylabel with angle 90° */ + Xget_str_length(text, &wlen, &wheight, DEVDEP(currentgraph).font90, NULL, 0); + + XftDrawStringUtf8( + DEVDEP(currentgraph).draw, &DEVDEP(currentgraph).color, DEVDEP(currentgraph).font90, + x + (int)(1.5 * wlen), currentgraph->absolute.height - y + (int)(0.5 * wheight), (FcChar8*)text, strlen(text)); + } + else + fprintf(stderr, " Xft: angles other than 0 or 90 are not supported in ngspice\n"); + return 0; } +int X11_DefineXft(GRAPH *graph) +{ +/* font selection with rotation */ + XftPattern *new_pat = XftPatternCreate(); // the pattern we will use for rotating + XftPatternAddString(new_pat, XFT_FAMILY, DEVDEP(graph).fname); + XftPatternAddDouble (new_pat, XFT_PIXEL_SIZE, (double)DEVDEP(graph).fsize); + + + XftResult rot_result; + XftPattern *rot_pat = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ + DEVDEP(graph).font0 = XftFontOpenPattern(display, rot_pat); + if(DEVDEP(graph).font0 == NULL) { + fprintf(stderr, "Can't load font pattern %s\n", DEVDEP(graph).fname); + } + + /* for angle 90 deg */ + XftMatrix m; + XftMatrixInit(&m); + int angle = 90; + XftMatrixRotate(&m,cos(M_PI*angle/180.),sin(M_PI*angle/180.)); + XftPatternAddMatrix (new_pat, XFT_MATRIX,&m); + + XftPattern *rot_pat2 = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ + DEVDEP(graph).font90 = XftFontOpenPattern(display, rot_pat2); + + XftPatternDestroy(new_pat); + + Colormap cmap = DefaultColormap(display, 0); + XftColor color; + XftColorAllocName(display, DefaultVisual(display, 0), cmap, DEVDEP(graph).txtcolor, &color); + DEVDEP(graph).color = color; + DEVDEP(graph).cmap = cmap; + DEVDEP(graph).draw = XftDrawCreate( + display, DEVDEP(graph).window, DefaultVisual(display, 0), cmap + ); + return 0; +} + int X11_DefineColor(int colorid, double red, double green, double blue) { @@ -1001,6 +1028,11 @@ void RemoveWindow(GRAPH *graph) if (old_x11) XFreeFont(display, DEVDEP(graph).font); XFreeGC(display, DEVDEP(graph).gc); + + XftFontClose( display, DEVDEP(graph).font0); + XftFontClose( display, DEVDEP(graph).font90); + XftDrawDestroy(DEVDEP(graph).draw); + XftColorFree(display, DefaultVisual(display, 0), DEVDEP(graph).cmap, &DEVDEP(graph).color); } if (graph == currentgraph) @@ -1200,7 +1232,7 @@ linear_arc(int x0, int y0, int radius, double theta, double delta_theta) /* After font selection for XftTextExtentsUtf8 * to measure character string length. - * Same as rotation below, but 0 angle */ + * Same as rotation below, but 0° angle */ static int Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* foname, int fsize) { XGlyphInfo extents; From 4d9167c44614b972fa45c354a79d3b23f0e52902 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 28 Dec 2019 14:34:46 +0100 Subject: [PATCH 44/98] update and unify font handling --- src/winmain.c | 97 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index 5d98ae2be..aba9a260d 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -117,7 +117,9 @@ static int VisibleRows = 10; /* Number of visible lines in text window static BOOL DoUpdate = FALSE; /* Update text window */ static WNDPROC swProc = NULL; /* original string window procedure */ static WNDPROC twProc = NULL; /* original text window procedure */ -static HFONT sfont; /* Font for source and analysis window */ +static HFONT efont; /* Font for element windows */ +static HFONT tfont; /* Font for text window */ +static HFONT sfont; /* Font for string window */ extern bool ft_ngdebug; /* some additional debug info printed */ extern bool ft_batchmode; @@ -210,6 +212,8 @@ SetAnalyse(char *Analyse, /* in: analysis type */ WaitForIdle(); + OldAn[0] = '\0'; + if (((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) || !strcmp(Analyse, "or")) return; @@ -263,14 +267,16 @@ SetAnalyse(char *Analyse, /* in: analysis type */ wchar_t tw[256]; swprintf(sw, 256, L"%S", s); swprintf(tw, 256, L"%S", t); + /* Analysis window */ SetWindowTextW(hwAnalyse, sw); + /* ngspice task bar */ SetWindowTextW(hwMain, tw); #endif InvalidateRgn(hwAnalyse, NULL, TRUE); + UpdateWindow(hwAnalyse); InvalidateRgn(hwMain, NULL, TRUE); + UpdateWindow(hwMain); } - UpdateWindow(hwAnalyse); - UpdateWindow(hwMain); } @@ -544,7 +550,7 @@ MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) default: DEFAULT_AFTER: -#ifdef EXT_ASC +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); #else return DefWindowProcW(hwnd, uMsg, wParam, lParam); @@ -640,7 +646,7 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else { history_reset_pos(*pp_hi); - } + } strcpy(SBuffer + n_char_returned, CRLF); ClearInput(); @@ -775,7 +781,7 @@ Element_OnPaint(HWND hwnd) o = GetSysColorBrush(COLOR_BTNFACE); FillRect(hdc, &s, o); SetBkMode(hdc, TRANSPARENT); - SelectObject(hdc, sfont); + SelectObject(hdc, efont); ExtTextOutW(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, bufferW, (unsigned)i, NULL); #endif /* End */ @@ -952,7 +958,7 @@ MakeArgcArgv(char *cmdline, int *argc, char ***argv) /* Main entry point for our Windows application */ -#ifdef EXT_ASC +#ifdef EXT_ASC int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) #elif __MINGW32__ /* MINGW bug not knowing wWinMain */ @@ -1052,7 +1058,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR #endif /* Define text window class */ -#ifdef EXT_ASC +#ifdef EXT_ASC if (!GetClassInfo(NULL, "EDIT", &twTextClass)) goto THE_END; @@ -1076,7 +1082,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR #endif /* Define string window class */ -#ifdef EXT_ASC +#ifdef EXT_ASC if (!GetClassInfo(NULL, "EDIT", &swStringClass)) goto THE_END; @@ -1100,7 +1106,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR #endif /* Define status element class */ -#ifdef EXT_ASC +#ifdef EXT_ASC hwElementClass.style = CS_HREDRAW | CS_VREDRAW; hwElementClass.lpfnWndProc = ElementWindowProc; hwElementClass.cbClsExtra = 0; @@ -1129,9 +1135,19 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR goto THE_END; #endif - /* Font for element status windows (source, analysis) */ - sfont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, L""); -// sfont = CreateFontW(15, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); /*Create main window */ + /* Font for element status windows (source, analysis, Quit button) */ + efont = CreateFontW(16, 6, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + ANTIALIASED_QUALITY, VARIABLE_PITCH, L""); +/* efont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, VARIABLE_PITCH, L"Segoe UI");*/ +/* efont = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier");*/ + if (!efont) + efont = GetStockFont(ANSI_FIXED_FONT); + #ifdef EXT_ASC SystemParametersInfo(SPI_GETWORKAREA, 0, &wsize, 0); #else @@ -1148,7 +1164,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); #endif #else -#ifdef EXT_ASC +#ifdef EXT_ASC hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 0, 0, ix, iy, NULL, NULL, hInst, NULL); #else @@ -1173,17 +1189,15 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR if (!twText) goto THE_END; - /* Ansii fixed font */ -#ifdef EXT_ASC +#ifdef EXT_ASC { HDC textDC; - HFONT font; TEXTMETRIC tm; - font = GetStockFont(ANSI_FIXED_FONT); - SetWindowFont(twText, font, FALSE); + tfont = GetStockFont(ANSI_FIXED_FONT); + SetWindowFont(twText, tfont, FALSE); textDC = GetDC(twText); if (textDC) { - SelectObject(textDC, font); + SelectObject(textDC, tfont); if (GetTextMetrics(textDC, &tm)) { RowHeight = tm.tmHeight; WinLineWidth = 90 * tm.tmAveCharWidth; @@ -1192,19 +1206,19 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR } } #else - { + { HDC textDC; - HFONT font; TEXTMETRICW tm; -// font = CreateFontW(14, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Lucida Console"); -// if(!font) - font = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); - if(!font) - font = GetStockFont(ANSI_FIXED_FONT); - SetWindowFont( twText, font, FALSE); + tfont = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, + FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); + /* Ansi fixed font */ + if(!tfont) + tfont = GetStockFont(ANSI_FIXED_FONT); + SetWindowFont( twText, tfont, FALSE); textDC = GetDC( twText); if (textDC) { - SelectObject( textDC, font); + SelectObject( textDC, tfont); if (GetTextMetricsW( textDC, &tm)) { RowHeight = tm.tmHeight; WinLineWidth = 90 * tm.tmAveCharWidth; @@ -1216,7 +1230,14 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR /* Create string window for input. Give a handle to history info to * the window for saving and retrieving commands */ -#ifdef EXT_ASC + /* Font for element status windows (source, analysis) */ + sfont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + ANTIALIASED_QUALITY, VARIABLE_PITCH, L""); + /* Ansi fixed font */ + if(!sfont) + sfont = GetStockFont(ANSI_FIXED_FONT); +#ifdef EXT_ASC swString = CreateWindowEx(WS_EX_NOPARENTNOTIFY, swClassName, swWindowName, ES_LEFT | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, /* Allow text to scroll */ @@ -1247,6 +1268,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR TEXTMETRICW tm; stringDC = GetDC(swString); if (stringDC) { + SelectObject(stringDC, sfont); if (GetTextMetricsW(stringDC, &tm)) LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize; ReleaseDC(swString, stringDC); @@ -1254,23 +1276,21 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR } #endif - - - + /* Element windows */ /* Create source window */ #ifdef EXT_ASC hwSource = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwSourceWindowName, WS_CHILD, 0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL); - if (!hwSource) - goto THE_END; #else hwSource = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwSourceWindowNameW, WS_CHILD, 0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL); - if (!hwSource) goto THE_END; #endif + if (!hwSource) + goto THE_END; + SetWindowFont(hwSource, efont, FALSE); /* Create analysis window */ #ifdef EXT_ASC @@ -1285,6 +1305,8 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR if (!hwAnalyse) goto THE_END; + SetWindowFont(hwAnalyse, efont, FALSE); + /* Create "Quit" button */ #ifdef EXT_ASC hwQuitButton = CreateWindow("BUTTON", "Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength, @@ -1296,6 +1318,9 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR if (!hwQuitButton) goto THE_END; + + SetWindowFont(hwQuitButton, efont, FALSE); + /* Define a minimum width */ int MinWidth = AnalyseLength + SourceLength + QuitButtonLength + 48; if (WinLineWidth < MinWidth) From 2ce891b66f4a482c1de45fa4bf2a124835e5df56 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 28 Dec 2019 14:35:09 +0100 Subject: [PATCH 45/98] some updates on fonts etc. --- .../utf-8/стекло/있어요/ext-utf8-2-있어요.cir | 6 +- examples/utf-8/стекло/있어요/ext-utf8-2.cir | 49 ++++++++++----- examples/utf-8/стекло/있어요/ext-utf8-3.cir | 59 ++++++++++++------- 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir index de061a23c..0253a4c77 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir @@ -2,7 +2,7 @@ .control set hcopydevtype = postscript set hcopypscolor=1 -set hcopyscale=0.5 +set hcopyscale=1 set color2=rgb:F/0/0 *setcs hcopyfont=Arial * @@ -33,9 +33,9 @@ plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' * for MS Windows only -*shell Start /B plot_5.ps +shell Start /B plot_5.ps * for CYGWIN -shell xterm -e gs plot_5.ps & +*shell xterm -e gs plot_5.ps & echo 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 echo אני יכול לאכול זכוכית וזה לא מזיק לי. diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2.cir b/examples/utf-8/стекло/있어요/ext-utf8-2.cir index de061a23c..45b073d54 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-2.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-2.cir @@ -1,46 +1,63 @@ * test de titré +* utf-8 UNICODE tests +* text snippets are from http://kermitproject.org/utf8.html +* English translation: I can eat glass and it doesn't hurt me. + .control set hcopydevtype = postscript -set hcopypscolor=1 -set hcopyscale=0.5 +set hcopypscolor=0 +set hcopypstxcolor=1 +set hcopyscale=1 set color2=rgb:F/0/0 *setcs hcopyfont=Arial * *setcs hcopyfont='Nimbus Mono-Regular' * for CYGWIN setcs hcopyfont='NimbusMonL-Bold' -*setcs hcopyfont='URWGothicL-Book' set hcopyfontsize=14 -* for CYGWIN -setcs xfont='Noto Sans CJK JP Medium' -set xfont_size=18 -*setcs xfont='Noto Sans Japanese' - +* the data to be plotted let x = vector(5) let y = exp(x) + +* MS Windows setcs wfont='Arial' set wfont_size=18 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' + +* Linux, CYGWIN +* Use font (*.ttc) from Cygwin distribution +setcs xfont='Noto Sans CJK JP Light' +set xfont_size=16 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 -*LINUX -*setcs xfont='Noto Sans Korean' plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog -* for CYGWIN -setcs xfont='Times New Roman' -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é Äü @µ€~' +* https://www.fontsc.com/font/tag/arabic +setcs xfont='Lateef' +set xfont_size=22 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني ' title 'Titré French Arabic 25' loglog +plot y vs x+0.001 xlabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني ' ylabel 'Jeg kan spise glas, det gør ikke ondt på mig. 26 ' title 'Titré Arabic 26' loglog + +* https://www.fontsc.com/font/tag/hebrew +setcs xfont='Alef' +set xfont_size=18 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' אני יכול לאכול זכוכית וזה לא מזיק לי. ' title 'Titré French Arabic 27' loglog +plot y vs x+0.001 xlabel ' אני יכול לאכול זכוכית וזה לא מזיק לי. ' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré Arabic 28' loglog + +hardcopy plot_6.ps y vs x xlabel 'Labellisé X' ylabel 'Jeg kan spise glas, det gør ikke ondt på mig.' title 'Titré Äü @µ€~' + * for MS Windows only *shell Start /B plot_5.ps * for CYGWIN -shell xterm -e gs plot_5.ps & +*shell xterm -e gs plot_5.ps & +shell gv plot_6.ps & echo 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 echo אני יכול לאכול זכוכית וזה לא מזיק לי. +echo ' أنا قادر على أكل الزجاج و هذا لا يؤلمني ' -*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' *quit .endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir index 2595dde34..8def1032a 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-3.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -1,33 +1,50 @@ -* test de titré 있어요 -* appologize for nonsense text - +* test de titré .control - -* for CYGWIN -setcs xfont='Noto Sans CJK JP Medium' -set xfont_size=18 +set hcopydevtype = postscript +set hcopypscolor=5 +set hcopypstxcolor=21 +set hcopyscale=1 +set color2=rgb:F/0/0 +setcs hcopyfont=Arial +set hcopyfontsize=18 let x = vector(5) let y = exp(x) -setcs wfont='Arial' +setcs wfont=Arial set wfont_size=18 -plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 11' -plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 12 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' -plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 13 私はガラスを食べられます。それは私を傷つけません' loglog -plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 14 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog +setcs xfont='Noto Sans CJK JP Medium' +*set xfont_size=16 -* for CYGWIN -setcs xfont='Times New Roman' -plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 15' loglog +set gridwidth=4 +set xbrushwidth=1 -setcs sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) -source ext-utf8-4.cir +*hardcopy -* better to put ouput into single quotes -echo 1 '私はガラスを食べられます。それは私を傷つけません' -echo 2 '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' +**plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +**gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel '있어요 tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +set gridwidth=1 +set xbrushwidth=4 + +**plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +**gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +**hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +**shell gv plot_5.ps & + +wrdata test.out y vs x +**asciiplot atest.out y vs x + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 *quit .endc From 4b00524b31d899866ced503623b9c394d52187f5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 28 Dec 2019 15:28:16 +0100 Subject: [PATCH 46/98] Regain static behaviour, keep removing compiler warning --- src/winmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/winmain.c b/src/winmain.c index aba9a260d..37b261f87 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -212,7 +212,7 @@ SetAnalyse(char *Analyse, /* in: analysis type */ WaitForIdle(); - OldAn[0] = '\0'; + OldAn[127] = '\0'; if (((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) || !strcmp(Analyse, "or")) return; From 74b95a3069163f1abb3da41aad393630381d8e8f Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 30 Dec 2019 18:32:58 +0100 Subject: [PATCH 47/98] checking for Xft library defines HAVE_LIBXFT upon success --- configure.ac | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index f28ea1083..9bd95085e 100644 --- a/configure.ac +++ b/configure.ac @@ -668,16 +668,10 @@ fi # Checks for X libraries - if X11 wasn't found then don't make following # tests and compile without X11 support - otherwise, check if the following # libraries are present (error if they are not) -# In CYGWIN library ordering has to be changed. Is this compatible to LINUX? # XShmAttach is a struct in CYGWIN, not a function -# SJB: 13th march 2005 -# Library order is giving linker warnings on MacOSX -# It's not clear to me which order is required for Cygwin (see comment above) -# and neither can I find any authoritative answer for the correct link order -# for MacOSX or Linux, but -# -lXaw -lXmu -lXt -lXext -lX11 -# seems to be the popular choice. -# (The previous order was -lX11 -lXt -lXext -lXmu -lXaw) +# Library order is +# -lXaw -lXmu -lXt -lXext -lX11 (-lXft -lfontconfig -lXrender -lfreetype) +# Xft is optional, allows text rotation in plots if test "x$no_x" != xyes ; then X_CFLAGS="$X_CFLAGS -I/usr/include/freetype2" @@ -688,11 +682,16 @@ if test "x$no_x" != xyes ; then X_LIBS="$X_LIBS -lXt" AC_CHECK_LIB([Xext], [XShmAttach], [X_LIBS="$X_LIBS -lXext"], [AC_MSG_ERROR([Couldn't find Xext library])], [$X_LIBS $X_EXTRA_LIBS]) - AC_CHECK_LIB([Xft], [main], [X_LIBS="$X_LIBS -lXft"], - [AC_MSG_ERROR([Couldn't find Xft library])], [$X_LIBS $X_EXTRA_LIBS]) X_LIBS="$X_LIBS -lX11" - AC_CHECK_LIB([fontconfig], [main], [X_LIBS="$X_LIBS -lfontconfig"], - [AC_MSG_ERROR([Couldn't find fontconfig library])], [$X_LIBS $X_EXTRA_LIBS]) + AC_CHECK_LIB([Xft], [main], + [AC_DEFINE([HAVE_LIBXFT], [], [Have xft routines in libxft]) + LIBS="$LIBS -lXft" + AC_CHECK_LIB([fontconfig], [main], [X_LIBS="$X_LIBS -lfontconfig"], + [AC_MSG_ERROR([Couldn't find fontconfig library])], [$X_LIBS $X_EXTRA_LIBS]) + AC_CHECK_LIB([Xrender], [main], [X_LIBS="$X_LIBS -lXrender"], + [AC_MSG_ERROR([Couldn't find Xrender library])], [$X_LIBS $X_EXTRA_LIBS]) + AC_CHECK_LIB([freetype], [main], [X_LIBS="$X_LIBS -lfreetype"], + [AC_MSG_ERROR([Couldn't find freetype library])], [$X_LIBS $X_EXTRA_LIBS])]) has_no_x=false else AC_DEFINE([X_DISPLAY_MISSING]) @@ -719,7 +718,7 @@ if test "x$enable_oldapps" = xyes ; then AC_MSG_RESULT([ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx nghelp are made.]) else AC_MSG_RESULT([ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx nghelp are not made.]) - AC_MSG_RESULT([No internal help available.]) + AC_MSG_RESULT([No internal help available.]) AC_DEFINE([NOINTHELP], [1], [Internal (old) help not available]) fi AM_CONDITIONAL([OLDAPPS], [test "x$enable_oldapps" = xyes]) From f07d5ef5dc8669ca86fa7108d07796779d11913a Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 30 Dec 2019 18:36:19 +0100 Subject: [PATCH 48/98] Add preprocessor macro OS_COMPILED --- configure.ac | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/configure.ac b/configure.ac index 9bd95085e..23d3fea5e 100644 --- a/configure.ac +++ b/configure.ac @@ -296,6 +296,32 @@ else dprefix=$prefix fi +#### +### check for operating system at compile time +case $host_os in + *mingw* | *msys* ) + AC_DEFINE([OS_COMPILED], [1], [MINGW for MS Windows]) + ;; + *cygwin* ) + AC_DEFINE([OS_COMPILED], [2], [Cygwin for MS Windows]) + ;; + *freebsd* ) + AC_DEFINE([OS_COMPILED], [3], [FreeBSD]) + ;; + *openbsd* ) + AC_DEFINE([OS_COMPILED], [4], [OpenBSD]) + ;; + *solaris* ) + AC_DEFINE([OS_COMPILED], [5], [Solaris]) + ;; + *linux* ) + AC_DEFINE([OS_COMPILED], [6], [Linux]) + ;; + * ) + AC_DEFINE([OS_COMPILED], [7], [Other Operating System]) + ;; +esac + ########################################################################## # # ngspice as shared library (ngspice.so or ngspice.dll) From 7af5ae01080998ffae78e92b4bd14a621367e350 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 30 Dec 2019 18:46:53 +0100 Subject: [PATCH 49/98] add macOS to OS_COMPILED --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 23d3fea5e..ddeef170d 100644 --- a/configure.ac +++ b/configure.ac @@ -317,8 +317,11 @@ case $host_os in *linux* ) AC_DEFINE([OS_COMPILED], [6], [Linux]) ;; + *darwin* ) + AC_DEFINE([OS_COMPILED], [7], [macOS]) + ;; * ) - AC_DEFINE([OS_COMPILED], [7], [Other Operating System]) + AC_DEFINE([OS_COMPILED], [8], [Other Operating System]) ;; esac From 3031cb5f65d664932fa8b2e4388e74fabbe5b62a Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 1 Jan 2020 11:15:57 +0100 Subject: [PATCH 50/98] fix remaining bugs when EXT_ASC is defined --- src/frontend/wdisp/windisp.c | 4 ++-- src/winmain.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index f6b2a4078..dacb22b9c 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -278,10 +278,10 @@ int WIN_Init(void) lf.lfQuality = 0; lf.lfPitchAndFamily = 0; /* set up fonts */ - if (!cp_getvar("wfont", CP_STRING, lf.lfFaceName)) { + if (!cp_getvar("wfont", CP_STRING, lf.lfFaceName, strlen(lf.lfFaceName))) { (void)lstrcpy(lf.lfFaceName, DEF_FONTW); } - if (!cp_getvar("wfont_size", CP_NUM, &(lf.lfHeight))) { + if (!cp_getvar("wfont_size", CP_NUM, &(lf.lfHeight), 0)) { lf.lfHeight = 18; } PlotFont = CreateFontIndirect(&lf); diff --git a/src/winmain.c b/src/winmain.c index 37b261f87..9e7be66b7 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -1159,6 +1159,7 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR const int iyt = iy / 3; /* height of screen divided by 3 */ #ifdef EXT_ASC hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); #else hwMain = CreateWindowW(hwClassNameW, hwWindowNameW, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); From bbf11e0bd36c9e6b7022ca7cacb1b365384c8b38 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 1 Jan 2020 11:17:57 +0100 Subject: [PATCH 51/98] replace old_x11 by HAVE_LIBXFT defined in configure --- src/frontend/inpcom.c | 2 +- src/frontend/plotting/grid.c | 36 +++++----- src/frontend/plotting/x11.c | 125 ++++++++++++++++++----------------- 3 files changed, 85 insertions(+), 78 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 78c6e8866..64d40ba44 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1338,7 +1338,7 @@ static char *inp_pathresolve(const char *name) if (stat(name, &st) == 0) return copy(name); -#if defined(__MINGW32__) || defined(_MSC_VER) +#if !defined(EXT_ASC) && (defined(__MINGW32__) || defined(_MSC_VER)) wchar_t wname[BSIZE_SP]; if (MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, 2 * (int)strlen(name) + 1) == 0) { fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n", GetLastError()); diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c index 588da69ae..6342a5e83 100644 --- a/src/frontend/plotting/grid.c +++ b/src/frontend/plotting/grid.c @@ -32,14 +32,9 @@ typedef tWindowData *tpWindowData; /* pointer to it */ #endif #ifndef X_DISPLAY_MISSING -extern bool old_x11; extern int X11_GetLenStr(GRAPH *gr, char* instring); #endif -#ifndef X_DISPLAY_MISSING -extern bool old_x11; -#endif - #define RAD_TO_DEG (180.0 / M_PI) #define RELPOSXUNIT 0.6 /* old position of the UNIT label */ @@ -163,10 +158,12 @@ gr_redrawgrid(GRAPH *graph) wlen++; i++; } +#ifdef HAVE_LIBXFT /* string lenth in pixels */ int strsize = X11_GetLenStr(graph, graph->grid.xlabel); DevDrawText(graph->grid.xlabel, (int)((graph->absolute.width - strsize) / 2), graph->fontheight, 0); + /* fix the position of the UNIT label */ if (RELPOSXUNIT * graph->absolute.width < ((graph->absolute.width + strsize) / 2 + graph->fontwidth)) unitshift = (int)((graph->absolute.width + strsize) / 2 @@ -174,6 +171,12 @@ gr_redrawgrid(GRAPH *graph) + graph->fontwidth; else unitshift = 0; /* reset for next plot window */ +#else + DevDrawText(graph->grid.xlabel, + (int) (graph->absolute.width * 0.35), graph->fontheight, + 0); + unitshift = 0; +#endif } #endif #ifdef HAS_WINGUI @@ -256,21 +259,20 @@ gr_redrawgrid(GRAPH *graph) } } #endif -#ifndef X_DISPLAY_MISSING - /* new x11 with xft and utf-8 */ - else if (!old_x11) { - /* calculate and add offsets in fcn X11_Text in X11.c */ - DevDrawText(graph->grid.ylabel, - 0, - /*vertical text, y is midpoint of graph height */ - (graph->absolute.height) / 2, 90); - } -#endif #endif else /* others */ DevDrawText(graph->grid.ylabel, - graph->fontwidth, - graph->absolute.height / 2, 90); +#if !defined(X_DISPLAY_MISSING) && defined(HAVE_LIBXFT) + /* new x11 with xft and utf-8 + * calculate and add offsets in fcn X11_Text in X11.c + */ + 0, +#else + graph->fontwidth, +#endif + /*vertical text, y is midpoint of graph height */ + graph->absolute.height / 2, 90); + } } diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 5e5ff6f6f..f8b3d1676 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -38,7 +38,9 @@ Author: 1988 Jeffrey M. Hsu # include # include +#ifdef HAVE_LIBXFT #include +#endif # ifdef DEBUG # include /* for _Xdebug */ @@ -60,8 +62,6 @@ Author: 1988 Jeffrey M. Hsu #define NUMCOLORS 20 -bool old_x11 = FALSE; /* if FALSE, use xft, if TRUE use old X11 text output */ - typedef struct x11info { Window window; int isopen; @@ -71,16 +71,18 @@ typedef struct x11info { int lastx, lasty; /* used in X_DrawLine */ int lastlinestyle; /* used in X_DrawLine */ Pixel colors[NUMCOLORS]; - /* use with xft */ char txtcolor[16]; char bgcolor[16]; char fname[BSIZE_SP]; int fsize; + /* use with xft */ +#ifdef HAVE_LIBXFT XftFont *font0; XftFont *font90; XftDraw* draw; XftColor color; Colormap cmap; +#endif } X11devdep; #define DEVDEP(g) (*((X11devdep *) (g)->devdep)) @@ -116,9 +118,10 @@ static void X_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy); static void linear_arc(int x0, int y0, int radius, double theta, double delta_theta); static void slopelocation(GRAPH *graph, int x0, int y0); static void zoomin(GRAPH *graph); +#ifdef HAVE_LIBXFT static int Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* name, int fsize); static int X11_DefineXft(GRAPH *graph); - +#endif //XtEventHandler static void handlekeypressed(Widget w, XtPointer clientdata, XEvent *ev, Boolean *continue_dispatch); static void handlebuttonev(Widget w, XtPointer graph, XEvent *ev, Boolean *continue_dispatch); @@ -158,9 +161,6 @@ X11_Init(void) return (1); } - if (cp_getvar("old_x11", CP_BOOL, NULL, 0)) - old_x11 = TRUE; - # ifdef DEBUG _Xdebug = 1; # endif @@ -259,12 +259,13 @@ initcolors(GRAPH *graph) (void) sprintf(buf, "color%d", i); if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) (void) strcpy(colorstring, colornames[i]); +#ifdef HAVE_LIBXFT /* text color info for xft */ - if((!old_x11) && (i == 1)) + if (i == 1) strncpy(DEVDEP(graph).txtcolor, colorstring, 15); - else if((!old_x11) && (i == 0)) + else if (i == 0) strncpy(DEVDEP(graph).bgcolor, colorstring, 15); - +#endif if (!XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)), colorstring, &visualcolor, &exactcolor)) { @@ -461,45 +462,44 @@ X11_NewViewport(GRAPH *graph) (void) strcpy(fontname, DEF_FONT); strncpy(DEVDEP(graph).fname, fontname, BSIZE_SP - 1); - if(old_x11) { - for (p = fontname; *p && *p <= ' '; p++) - ; +#ifndef HAVE_LIBXFT + for (p = fontname; *p && *p <= ' '; p++) + ; - if (p != fontname) { - for (q = fontname; *p; *q++ = *p++) - ; - *q = '\0'; - } - trys = 1; - while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { - sprintf(ErrorMessage, "can't open font %s", fontname); - strcpy(fontname, "fixed"); - if (trys > 1) { - internalerror(ErrorMessage); - RECOVERNEWVIEWPORT(); - return (1); - } - trys += 1; - } + if (p != fontname) { + for (q = fontname; *p; *q++ = *p++) + ; + *q = '\0'; } + trys = 1; + while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { + sprintf(ErrorMessage, "can't open font %s", fontname); + strcpy(fontname, "fixed"); + if (trys > 1) { + internalerror(ErrorMessage); + RECOVERNEWVIEWPORT(); + return (1); + } + trys += 1; + } +#endif /* font size */ if (!cp_getvar("xfont_size", CP_NUM, &xfont_size, 0)) xfont_size = 16; - if(old_x11) { - graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - - DEVDEP(graph).font->min_bounds.lbearing + 1; - graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + - DEVDEP(graph).font->max_bounds.descent + 1; - } - else { - int wl, wh; - Xget_str_length("ABCD", &wl, &wh, NULL, fontname, xfont_size); - graph->fontwidth = (int)(wl / 4); - graph->fontheight = wh; - DEVDEP(graph).fsize = xfont_size; - } +#ifndef HAVE_LIBXFT + graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - + DEVDEP(graph).font->min_bounds.lbearing + 1; + graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + + DEVDEP(graph).font->max_bounds.descent + 1; +#else + int wl, wh; + Xget_str_length("ABCD", &wl, &wh, NULL, fontname, xfont_size); + graph->fontwidth = (int)(wl / 4); + graph->fontheight = wh; + DEVDEP(graph).fsize = xfont_size; +#endif XtRealizeWidget(DEVDEP(graph).shell); @@ -513,15 +513,14 @@ X11_NewViewport(GRAPH *graph) gcvalues.line_width = MW_LINEWIDTH; gcvalues.cap_style = CapNotLast; gcvalues.function = GXcopy; - if (old_x11) { - gcvalues.font = DEVDEP(graph).font->fid; - DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, - GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); - } - else - DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, - GCLineWidth | GCCapStyle | GCFunction, &gcvalues); - +#ifndef HAVE_LIBXFT + gcvalues.font = DEVDEP(graph).font->fid; + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); +#else + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + GCLineWidth | GCCapStyle | GCFunction, &gcvalues); +#endif /* should absolute.positions really be shell.pos? */ graph->absolute.xpos = DEVDEP(graph).view->core.x; graph->absolute.ypos = DEVDEP(graph).view->core.y; @@ -535,7 +534,9 @@ X11_NewViewport(GRAPH *graph) cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); - X11_DefineXft(graph); + #ifdef HAVE_LIBXFT + X11_DefineXft(graph); +#endif /* WM_DELETE_WINDOW protocol */ atom_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); @@ -614,7 +615,7 @@ X11_Text(char *text, int x, int y, int angle) int wlen = 0, wheight = 0; - if(old_x11) { +#ifndef HAVE_LIBXFT if (DEVDEP(currentgraph).isopen) XDrawString(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x, @@ -623,9 +624,7 @@ X11_Text(char *text, int x, int y, int angle) text, (int) strlen(text)); /* note: unlike before, we do not save any text here */ - return 0; - } - +#else /* Draw text */ if(angle == 0) { XftDrawStringUtf8( @@ -644,10 +643,11 @@ X11_Text(char *text, int x, int y, int angle) else fprintf(stderr, " Xft: angles other than 0 or 90 are not supported in ngspice\n"); +#endif return 0; } - +#ifdef HAVE_LIBXFT int X11_DefineXft(GRAPH *graph) { /* font selection with rotation */ @@ -685,6 +685,7 @@ int X11_DefineXft(GRAPH *graph) ); return 0; } +#endif int X11_DefineColor(int colorid, double red, double green, double blue) @@ -1025,14 +1026,16 @@ void RemoveWindow(GRAPH *graph) /* MW. Not sure but DestroyGraph might free() too much - try Xt...() first */ XtUnmapWidget(DEVDEP(graph).shell); XtDestroyWidget(DEVDEP(graph).shell); - if (old_x11) - XFreeFont(display, DEVDEP(graph).font); +#ifndef HAVE_LIBXFT + XFreeFont(display, DEVDEP(graph).font); +#endif XFreeGC(display, DEVDEP(graph).gc); - +#ifdef HAVE_LIBXFT XftFontClose( display, DEVDEP(graph).font0); XftFontClose( display, DEVDEP(graph).font90); XftDrawDestroy(DEVDEP(graph).draw); XftColorFree(display, DefaultVisual(display, 0), DEVDEP(graph).cmap, &DEVDEP(graph).color); +#endif } if (graph == currentgraph) @@ -1230,6 +1233,7 @@ linear_arc(int x0, int y0, int radius, double theta, double delta_theta) } } +#ifdef HAVE_LIBXFT /* After font selection for XftTextExtentsUtf8 * to measure character string length. * Same as rotation below, but 0° angle */ @@ -1265,6 +1269,7 @@ X11_GetLenStr(GRAPH *gr, char* instring) Xget_str_length(instring, &wl, &wh, NULL, DEVDEP(gr).fname, DEVDEP(gr).fsize); return wl; } +#endif #else From acd675e5ebfd65fed564b83239454183ab4b5b2d Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 1 Jan 2020 11:18:48 +0100 Subject: [PATCH 52/98] check for libxft, if successful, then define HAVE_XFT --- configure.ac | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index ddeef170d..9b3275438 100644 --- a/configure.ac +++ b/configure.ac @@ -713,14 +713,20 @@ if test "x$no_x" != xyes ; then [AC_MSG_ERROR([Couldn't find Xext library])], [$X_LIBS $X_EXTRA_LIBS]) X_LIBS="$X_LIBS -lX11" AC_CHECK_LIB([Xft], [main], - [AC_DEFINE([HAVE_LIBXFT], [], [Have xft routines in libxft]) - LIBS="$LIBS -lXft" - AC_CHECK_LIB([fontconfig], [main], [X_LIBS="$X_LIBS -lfontconfig"], - [AC_MSG_ERROR([Couldn't find fontconfig library])], [$X_LIBS $X_EXTRA_LIBS]) - AC_CHECK_LIB([Xrender], [main], [X_LIBS="$X_LIBS -lXrender"], - [AC_MSG_ERROR([Couldn't find Xrender library])], [$X_LIBS $X_EXTRA_LIBS]) - AC_CHECK_LIB([freetype], [main], [X_LIBS="$X_LIBS -lfreetype"], - [AC_MSG_ERROR([Couldn't find freetype library])], [$X_LIBS $X_EXTRA_LIBS])]) + [AC_DEFINE([HAVE_LIBXFT], [1], [Have xft routines in libxft])] + X_LIBS="$X_LIBS -lXft -lfontconfig -lXrender -lfreetype" + has_xft=yes, + [has_xft=no], [$X_LIBS $X_EXTRA_LIBS]) + + if test "x$has_xft" = xyes ; then + AC_CHECK_LIB([fontconfig], [main], [], + [AC_MSG_ERROR([Couldn't find fontconfig library])], [$X_LIBS $X_EXTRA_LIBS]) +# AC_CHECK_LIB([Xrender], [main], [], +# [AC_MSG_ERROR([Couldn't find Xrender library])], [$X_LIBS $X_EXTRA_LIBS]) + AC_CHECK_LIB([freetype], [main], [], + [AC_MSG_ERROR([Couldn't find freetype library])], [$X_LIBS $X_EXTRA_LIBS]) + fi + has_no_x=false else AC_DEFINE([X_DISPLAY_MISSING]) From 03d14660cfba7f5a2b53650a9c2b465bb071f6a7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 1 Jan 2020 11:20:02 +0100 Subject: [PATCH 53/98] add optional HAVE_XFT and EXT_ASC for Visual Studio --- visualc/src/include/ngspice/config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/visualc/src/include/ngspice/config.h b/visualc/src/include/ngspice/config.h index 31034f571..a3c6b90ed 100644 --- a/visualc/src/include/ngspice/config.h +++ b/visualc/src/include/ngspice/config.h @@ -551,3 +551,7 @@ /* Define as `fork' if `vfork' does not work. */ #define vfork fork + +#define HAVE_XFT + +#define EXT_ASC From 9b7766f867ba0d16d1d7a4ad417710ef879ada2f Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 2 Jan 2020 00:30:53 +0100 Subject: [PATCH 54/98] remove typo --- examples/utf-8/стекло/ext-ascii-1.cir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/utf-8/стекло/ext-ascii-1.cir b/examples/utf-8/стекло/ext-ascii-1.cir index 677d15ff1..5831febe1 100644 --- a/examples/utf-8/стекло/ext-ascii-1.cir +++ b/examples/utf-8/стекло/ext-ascii-1.cir @@ -23,6 +23,6 @@ plot y vs x hardcopy plot_4.ps y vs x plot y vs x xlabel 'Labellis X' ylabel 'Labellise Y' title 'Titr' -hardcopy plot_5.ps y vs x xlabel 'Labellis X' title 'Labellis Y' title 'Titr' +hardcopy plot_5.ps y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' .endc From 076037a34c9dce1d5847b4a6956b05975a5defd4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 2 Jan 2020 13:38:32 +0100 Subject: [PATCH 55/98] generate variable oscompiled test for variable --- configure.ac | 2 +- examples/utf-8/стекло/os_compiled.sp | 34 +++++++++++++++++++++++++ src/frontend/init.c | 37 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 examples/utf-8/стекло/os_compiled.sp diff --git a/configure.ac b/configure.ac index 9b3275438..215ac59aa 100644 --- a/configure.ac +++ b/configure.ac @@ -321,7 +321,7 @@ case $host_os in AC_DEFINE([OS_COMPILED], [7], [macOS]) ;; * ) - AC_DEFINE([OS_COMPILED], [8], [Other Operating System]) + AC_DEFINE([OS_COMPILED], [0], [Other Operating System]) ;; esac diff --git a/examples/utf-8/стекло/os_compiled.sp b/examples/utf-8/стекло/os_compiled.sp new file mode 100644 index 000000000..dec8ddcfa --- /dev/null +++ b/examples/utf-8/стекло/os_compiled.sp @@ -0,0 +1,34 @@ +*ng_script test for oscompiled + +.control +if $oscompiled = 0 + echo [0], Other +endif +if $oscompiled = 1 + echo [1], MINGW for MS Windows +endif +if $oscompiled = 2 + echo [2], Cygwin for MS Windows +endif +if $oscompiled = 3 + echo [3], FreeBSD +endif +if $oscompiled = 4 + echo [4], OpenBSD +endif +if $oscompiled = 5 + echo [5], Solaris +endif +if $oscompiled = 6 + echo [6], Linux +endif +if $oscompiled = 7 + echo [7], macOS +endif +if $oscompiled = 8 + echo [8], Visual Studio for MS Windows +endif + +.endc + +.end diff --git a/src/frontend/init.c b/src/frontend/init.c index 5e963e585..fe494a34d 100644 --- a/src/frontend/init.c +++ b/src/frontend/init.c @@ -30,4 +30,41 @@ cp_init(void) /* io redirection in streams.c: cp_in set to cp_curin etc. */ cp_ioreset(); + + /*set a variable oscompiled containing the OS at compile time + [0], Other + [1], MINGW for MS Windows + [2], Cygwin for MS Windows + [3], FreeBSD + [4], OpenBSD + [5], Solaris + [6], Linux + [7], macOS + [8], Visual Studio for MS Windows + The variable may be used in a .control section to perform OS + specific actions (setting fonts etc.). + */ + int itmp; +#if OS_COMPILED == 1 + itmp = 1; +#elif OS_COMPILED == 2 + itmp = 2; +#elif OS_COMPILED == 3 + itmp = 3; +#elif OS_COMPILED == 4 + itmp = 4; +#elif OS_COMPILED == 5 + itmp = 5; +#elif OS_COMPILED == 6 + itmp = 6; +#elif OS_COMPILED == 7 + itmp = 7; +#else + itmp = 0; +#endif + /* not using configure.ac */ +#ifdef _MSC_VER + itmp = 8; +#endif + cp_vset("oscompiled", CP_NUM, &itmp); } From a951d121ea35e3a204726026312c537726cb72b3 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 2 Jan 2020 13:39:39 +0100 Subject: [PATCH 56/98] undo EXT_ASC --- visualc/src/include/ngspice/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualc/src/include/ngspice/config.h b/visualc/src/include/ngspice/config.h index a3c6b90ed..983d1b037 100644 --- a/visualc/src/include/ngspice/config.h +++ b/visualc/src/include/ngspice/config.h @@ -554,4 +554,4 @@ #define HAVE_XFT -#define EXT_ASC +//#define EXT_ASC From 901ce79509d8b1388532cc6be04c02f0ad40fdf8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 2 Jan 2020 19:17:13 +0100 Subject: [PATCH 57/98] use variable 'oscompiled' to specialize for various OSs --- examples/utf-8/стекло/있어요/ext-utf8-3.cir | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir index 8def1032a..ec84e4730 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-3.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -35,9 +35,19 @@ plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラス * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" **gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -**hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' -*shell Start /B plot_5.ps -**shell gv plot_5.ps & +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +if ($oscompiled = 1) or ($oscompiled = 8) + shell Start /B plot_5.ps +endif +if ($oscompiled = 2) + shell xterm -e gs plot_5.ps & +endif +if ($oscompiled = 6) + shell gv plot_5.ps & +endif +if ($oscompiled = 7) + shell open -a Preview plot_5.ps & +endif wrdata test.out y vs x **asciiplot atest.out y vs x From a709512a8629bccc3a4e6292203e18cbd20b08d3 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 14:04:42 +0100 Subject: [PATCH 58/98] add color selection to WinGui plots --- examples/utf-8/стекло/ext-utf8-c.cir | 53 +++++++++++++ src/frontend/wdisp/windisp.c | 114 ++++----------------------- visualc/vngspice.vcxproj | 3 + 3 files changed, 73 insertions(+), 97 deletions(-) create mode 100644 examples/utf-8/стекло/ext-utf8-c.cir diff --git a/examples/utf-8/стекло/ext-utf8-c.cir b/examples/utf-8/стекло/ext-utf8-c.cir new file mode 100644 index 000000000..5f6248666 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-c.cir @@ -0,0 +1,53 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 +*set color2=rgb:F/0/0 + +setcs hcopyfont=Arial +set hcopyfontsize=18 + + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans' +*set xfont_size=18 + +set gridwidth=4 +set xbrushwidth=1 +set color0=white +set color2=brown +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +set color0=black +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +set color0=yellow +set color1=black +set color2=blue +set gridwidth=1 +set xbrushwidth=4 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=black +set color2=pink +unset color1 +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +*shell gv plot_5.ps & + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index dacb22b9c..98fa313c7 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -103,6 +103,9 @@ static bool isblackold = TRUE; static int linewidth = 0; /* linewidth of grid and plot */ static int gridlinewidth = 0; /* linewidth of grid */ +extern void wincolor_init(COLORREF *ColorTable, int noc); +extern void wincolor_redo(COLORREF *ColorTable, int noc); + /****************************************************************************** WIN_Init() makes connection to graphics. We have to determine @@ -117,7 +120,6 @@ WIN_Init() does not yet open a window, this happens only in WIN_NewViewport() ******************************************************************************/ int WIN_Init(void) { - char colorstring[BSIZE_SP]; char facename[32]; #ifdef EXT_ASC @@ -132,75 +134,11 @@ int WIN_Init(void) dispdev->numlinestyles = 5; /* see implications in WinPrint! */ dispdev->numcolors = NumWinColors; - /* always, user may have set color0 to white */ - /* get background color information from spinit, only "white" - is recognized as a suitable option! */ - if (cp_getvar("color0", CP_STRING, colorstring, sizeof(colorstring))) { - if (cieq(colorstring, "white")) isblack = FALSE; - else isblack = TRUE; - } - - /* get linewidth information from spinit */ - if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) { - linewidth = 0; - } - if (linewidth < 0) { - linewidth = 0; - } - - /* get linewidth for grid from spinit */ - if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) - gridlinewidth = linewidth; - if (gridlinewidth < 0) - gridlinewidth = 0; - /* only for the first time: */ if (!IsRegistered) { - isblackold = isblack; + wincolor_init(ColorTable, NumWinColors); - /* Initialize colors */ - if (isblack) { - ColorTable[0] = RGB( 0, 0, 0); /* black = background */ - ColorTable[1] = RGB(255, 255, 255); /* white = text and grid */ - } - else { - ColorTable[0] = RGB(255, 255, 255); /* white = background */ - ColorTable[1] = RGB( 0, 0, 0); /* black = text and grid */ - } - - ColorTable[2] = RGB( 0, 255, 0); /* green = first line */ - ColorTable[3] = RGB(255, 0, 0); /* red */ - ColorTable[4] = RGB( 0, 0, 255); /* blue */ - ColorTable[5] = RGB(255, 255, 0); /* yellow */ - ColorTable[6] = RGB(255, 0, 255); /* violett */ - ColorTable[7] = RGB( 0, 255, 255); /* azur */ - ColorTable[8] = RGB(255, 128, 0); /* orange */ - ColorTable[9] = RGB(128, 64, 0); /* brown */ - ColorTable[10] = RGB(128, 0, 255); /* light violett */ - ColorTable[11] = RGB(255, 128, 128); /* pink */ - - /* 2. color bank (with different line style */ - if (isblack) { - ColorTable[12] = RGB(255, 255, 255); /* white */ - } - else { - ColorTable[12] = RGB( 0, 0, 0); /* black */ - } - - ColorTable[13] = RGB( 0, 255, 0); /* green */ - ColorTable[14] = RGB(255, 0, 0); /* red */ - ColorTable[15] = RGB( 0, 0, 255); /* blue */ - ColorTable[16] = RGB(255, 255, 0); /* yellow */ - ColorTable[17] = RGB(255, 0, 255); /* violett */ - ColorTable[18] = RGB( 0, 255, 255); /* azur */ - ColorTable[19] = RGB(255, 128, 0); /* orange */ - ColorTable[20] = RGB(128, 64, 0); /* brown */ - ColorTable[21] = RGB(128, 0, 255); /* light violett */ - ColorTable[22] = RGB(255, 128, 128); /* pink */ - - /* Ansii fixed font */ -// PlotFont = GetStockFont(ANSI_FIXED_FONT); #ifdef EXT_ASC /* register window class */ TheWndClass.lpszClassName = WindowName; @@ -241,28 +179,11 @@ int WIN_Init(void) TheWndClassW.cbWndExtra = sizeof(GRAPH *); if (!RegisterClassW(&TheWndClassW)) return 1; #endif - + IsRegistered = 1; } - /* not first time */ - else if (isblackold != isblack) { - if (isblack) { - ColorTable[0] = RGB( 0, 0, 0); /* black = background */ - ColorTable[1] = RGB(255, 255, 255); /* white = text and grid */ - } - else { - ColorTable[0] = RGB(255, 255, 255); /* white = background */ - ColorTable[1] = RGB( 0, 0, 0); /* black = text and grid */ - } - if (isblack) { - ColorTable[12] = RGB(255, 255, 255); /* white */ - } - else { - ColorTable[12] = RGB( 0, 0, 0); /* black */ - } + else + wincolor_redo(ColorTable, NumWinColors); - isblackold = isblack; - } - IsRegistered = 1; #ifdef EXT_ASC // lf.lfHeight = 18; lf.lfWidth = 0; @@ -756,15 +677,15 @@ int WIN_NewViewport(GRAPH *graph) if (!window) return 1; - /* change the background color of all windows (both new and already plotted) - by assessing the registered window class */ - if (isblack) { - SetClassLongPtr(window, GCLP_HBRBACKGROUND, (LONG_PTR)GetStockObject(BLACK_BRUSH)); - } - else { - SetClassLongPtr(window, GCLP_HBRBACKGROUND, (LONG_PTR)GetStockObject(WHITE_BRUSH)); - } + SetClassLongPtr(window, GCLP_HBRBACKGROUND, (LONG_PTR)GetStockObject(DC_BRUSH)); + + /* get the DC */ + dc = GetDC(window); + wd->hDC = dc; + /* set the background color */ + SelectObject(dc, GetStockObject(DC_BRUSH)); + SetDCBrushColor(dc, ColorTable[0]); wd->wnd = window; SetWindowLongPtr(window, 0, (LONG_PTR)graph); @@ -775,9 +696,8 @@ int WIN_NewViewport(GRAPH *graph) /* get the mask */ GetClientRect(window, &(wd->Area)); - /* get the DC */ - dc = GetDC(window); - wd->hDC = dc; + + /* set the Color Index */ wd->ColorIndex = 0; diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj index ba0762697..737d57b29 100644 --- a/visualc/vngspice.vcxproj +++ b/visualc/vngspice.vcxproj @@ -922,6 +922,7 @@ + @@ -939,6 +940,7 @@ + @@ -1531,6 +1533,7 @@ + From 66b3151dbd748b9b1ac6f1304cf82ab12b0bdf5d Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 14:05:42 +0100 Subject: [PATCH 59/98] enable color selection, if compiled with MINGW --- src/frontend/wdisp/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/wdisp/Makefile.am b/src/frontend/wdisp/Makefile.am index 423164907..8a0f5e640 100644 --- a/src/frontend/wdisp/Makefile.am +++ b/src/frontend/wdisp/Makefile.am @@ -7,6 +7,7 @@ libwindisp_la_SOURCES = \ windisp.h \ winprint.c \ winprint.h \ + wincolor.c \ ftegraf.h From f8c3c7c417bedfe494f7a620b2bdf3ec989fb040 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 14:06:39 +0100 Subject: [PATCH 60/98] add shell plotter selection as function of oscompiled --- examples/utf-8/стекло/ext-utf8-2.cir | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index fbeb07417..53f2072dc 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -40,7 +40,19 @@ echo 私はガラスを食べられます。それは私を傷つけません echo 我能吞下玻璃而不伤身体 hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' -shell Start /B plot_5.ps + +if ($oscompiled = 1) or ($oscompiled = 8) + shell Start /B plot_5.ps +endif +if ($oscompiled = 2) + shell xterm -e gs plot_5.ps & +endif +if ($oscompiled = 6) + shell gv plot_5.ps & +endif +if ($oscompiled = 7) + shell open -a Preview plot_5.ps & +endif echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 echo 私はガラスを食べられます。それは私を傷つけません From 85fd52e43e666f7b580bf2466b76c6572b109e9d Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 14:20:39 +0100 Subject: [PATCH 61/98] list of colors used --- src/include/ngspice/wincolornames.h | 169 ++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/include/ngspice/wincolornames.h diff --git a/src/include/ngspice/wincolornames.h b/src/include/ngspice/wincolornames.h new file mode 100644 index 000000000..0ef62ec81 --- /dev/null +++ b/src/include/ngspice/wincolornames.h @@ -0,0 +1,169 @@ +/* list of available colors + according to + https://www.codeproject.com/Articles/1276/Naming-Common-Colors +*/ + +#if !defined(__ID_COLOR_NAMES_H) +#define __ID_COLOR_NAMES_H + +struct colortable { + COLORREF rgbc; + char name[32]; + int R; + int G; + int B; +}; + +static struct colortable ctable[] = { + 0, "AliceBlue ",240,248,255, + 0, "AntiqueWhite ",250,235,215, + 0, "Aqua ", 0,255,255, + 0, "Aquamarine ",127,255,212, + 0, "Azure ",240,255,255, + 0, "Beige ",245,245,220, + 0, "Bisque ",255,228,196, + 0, "Black ", 0, 0, 0, + 0, "BlanchedAlmond ",255,255,205, + 0, "Blue ", 0, 0,255, + 0, "BlueViolet ",138, 43,226, + 0, "Brown ",165, 42, 42, + 0, "Burlywood ",222,184,135, + 0, "CadetBlue ", 95,158,160, + 0, "Chartreuse ",127,255, 0, + 0, "Chocolate ",210,105, 30, + 0, "Coral ",255,127, 80, + 0, "CornflowerBlue ",100,149,237, + 0, "Cornsilk ",255,248,220, + 0, "Crimson ",220, 20, 60, + 0, "Cyan ", 0,255,255, + 0, "DarkBlue ", 0, 0,139, + 0, "DarkCyan ", 0,139,139, + 0, "DarkGoldenRod ",184,134, 11, + 0, "DarkGray ",169,169,169, + 0, "DarkGreen ", 0,100, 0, + 0, "DarkKhaki ",189,183,107, + 0, "DarkMagenta ",139, 0,139, + 0, "DarkOliveGreen ", 85,107, 47, + 0, "DarkOrange ",255,140, 0, + 0, "DarkOrchid ",153, 50,204, + 0, "DarkRed ",139, 0, 0, + 0, "DarkSalmon ",233,150,122, + 0, "DarkSeaGreen ",143,188,143, + 0, "DarkSlateBlue ", 72, 61,139, + 0, "DarkSlateGray ", 47, 79, 79, + 0, "DarkTurquoise ", 0,206,209, + 0, "DarkViolet ",148, 0,211, + 0, "DeepPink ",255, 20,147, + 0, "DeepSkyBlue ", 0,191,255, + 0, "DimGray ",105,105,105, + 0, "DodgerBlue ", 30,144,255, + 0, "FireBrick ",178, 34, 34, + 0, "FloralWhite ",255,250,240, + 0, "ForestGreen ", 34,139, 34, + 0, "Fuchsia ",255, 0,255, + 0, "Gainsboro ",220,220,220, + 0, "GhostWhite ",248,248,255, + 0, "Gold ",255,215, 0, + 0, "GoldenRod ",218,165, 32, + 0, "Gray ",127,127,127, + 0, "Green ", 0,128, 0, + 0, "GreenYellow ",173,255, 47, + 0, "HoneyDew ",240,255,240, + 0, "HotPink ",255,105,180, + 0, "IndianRed ",205, 92, 92, + 0, "Indigo ", 75, 0,130, + 0, "Ivory ",255,255,240, + 0, "Khaki ",240,230,140, + 0, "Lavender ",230,230,250, + 0, "LavenderBlush ",255,240,245, + 0, "Lawngreen ",124,252, 0, + 0, "LemonChiffon ",255,250,205, + 0, "LightBlue ",173,216,230, + 0, "LightCoral ",240,128,128, + 0, "LightCyan ",224,255,255, + 0, "LightGoldenRodYellow ",250,250,210, + 0, "LightGreen ",144,238,144, + 0, "LightGrey ",211,211,211, + 0, "LightPink ",255,182,193, + 0, "LightSalmon ",255,160,122, + 0, "LightSeaGreen ", 32,178,170, + 0, "LightSkyBlue ",135,206,250, + 0, "LightSlateGray ",119,136,153, + 0, "LightSteelBlue ",176,196,222, + 0, "Light Violet ",128, 0,255, + 0, "LightYellow ",255,255,224, + 0, "Lime ", 0,255, 0, + 0, "LimeGreen ", 50,205, 50, + 0, "Linen ",250,240,230, + 0, "Magenta ",255, 0,255, + 0, "Maroon ",128, 0, 0, + 0, "MediumAquamarine ",102,205,170, + 0, "MediumBlue ", 0, 0,205, + 0, "MediumOrchid ",186, 85,211, + 0, "MediumPurple ",147,112,219, + 0, "MediumSeaGreen ", 60,179,113, + 0, "MediumSlateBlue ",123,104,238, + 0, "MediumSpringGreen ", 0,250,154, + 0, "MediumTurquoise ", 72,209,204, + 0, "MediumVioletRed ",199, 21,133, + 0, "MidnightBlue ", 25, 25,112, + 0, "MintCream ",245,255,250, + 0, "MistyRose ",255,228,225, + 0, "Moccasin ",255,228,181, + 0, "NavajoWhite ",255,222,173, + 0, "Navy ", 0, 0,128, + 0, "Navyblue ",159,175,223, + 0, "OldLace ",253,245,230, + 0, "Olive ",128,128, 0, + 0, "OliveDrab ",107,142, 35, + 0, "Orange ",255,165, 0, + 0, "OrangeRed ",255, 69, 0, + 0, "Orchid ",218,112,214, + 0, "PaleGoldenRod ",238,232,170, + 0, "PaleGreen ",152,251,152, + 0, "PaleTurquoise ",175,238,238, + 0, "PaleVioletRed ",219,112,147, + 0, "PapayaWhip ",255,239,213, + 0, "PeachPuff ",255,218,185, + 0, "Peru ",205,133, 63, + 0, "Pink ",255,192,203, + 0, "Plum ",221,160,221, + 0, "PowderBlue ",176,224,230, + 0, "Purple ",128, 0,128, + 0, "Red ",255, 0, 0, + 0, "RosyBrown ",188,143,143, + 0, "RoyalBlue ", 65,105,225, + 0, "SaddleBrown ",139, 69, 19, + 0, "Salmon ",250,128,114, + 0, "SandyBrown ",244,164, 96, + 0, "SeaGreen ", 46,139, 87, + 0, "SeaShell ",255,245,238, + 0, "Sienna ",160, 82, 45, + 0, "Silver ",192,192,192, + 0, "SkyBlue ",135,206,235, + 0, "SlateBlue ",106, 90,205, + 0, "SlateGray ",112,128,144, + 0, "Snow ",255,250,250, + 0, "SpringGreen ", 0,255,127, + 0, "SteelBlue ", 70,130,180, + 0, "Tan ",210,180,140, + 0, "Teal ", 0,128,128, + 0, "Thistle ",216,191,216, + 0, "Tomato ",255, 99, 71, + 0, "Turquoise ", 64,224,208, + 0, "Violet ",238,130,238, + 0, "Wheat ",245,222,179, + 0, "White ",255,255,255, + 0, "WhiteSmoke ",245,245,245, + 0, "Yellow ",255,255, 0, + 0, "YellowGreen ",139,205, 50 +}; + +char* stdcolornames[] = +{ + "black", "white", "green", "red", "blue", "yellow", "violet", + "azure", "orange", "brown", "light violet", "pink", + "white", "green", "red", "blue", "yellow", "violet", + "azure", "orange", "brown", "light violet", "pink" +}; +#endif // __ID_COLOR_NAMES From c1aa6d714281629d6efd105b8113684211f7e743 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 15:16:36 +0100 Subject: [PATCH 62/98] enable using setting colors by colornn with 0<=nn<=22 The name list of colors is given by https://www.codeproject.com/Articles/1276/Naming-Common-Colors --- examples/utf-8/стекло/ext-utf8-c.cir | 15 ++- src/frontend/wdisp/wincolor.c | 146 +++++++++++++++++++++++++++ src/frontend/wdisp/wincolor.h | 0 3 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 src/frontend/wdisp/wincolor.c create mode 100644 src/frontend/wdisp/wincolor.h diff --git a/examples/utf-8/стекло/ext-utf8-c.cir b/examples/utf-8/стекло/ext-utf8-c.cir index 5f6248666..4ee9ec66b 100644 --- a/examples/utf-8/стекло/ext-utf8-c.cir +++ b/examples/utf-8/стекло/ext-utf8-c.cir @@ -26,16 +26,21 @@ set color0=black plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" *gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -set color0=yellow -set color1=black -set color2=blue +set color0=Blue +set color1=Yellow +set color2=Lime set gridwidth=1 set xbrushwidth=4 plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog -*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +unset color1 +set color0=MediumBlue +set color2=Magenta +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=GreenYellow +set color2=Magenta +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog set color0=black set color2=pink -unset color1 plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" diff --git a/src/frontend/wdisp/wincolor.c b/src/frontend/wdisp/wincolor.c new file mode 100644 index 000000000..7ca5abe29 --- /dev/null +++ b/src/frontend/wdisp/wincolor.c @@ -0,0 +1,146 @@ +/* Copyright: Holger Vogt, 2020 */ +/* Three Clause BSD */ +/* Universal color table and retrival */ + + +#include "ngspice/ngspice.h" +#include "ngspice/cpextern.h" +#include "ngspice/hash.h" +#include "ngspice/macros.h" +#undef BOOLEAN +#include +#include "ngspice/wincolornames.h" + + + +static NGHASHPTR color_p; /* color hash table */ +static COLORREF get_wincolor(char* name, int nocolor); + +void wincolor_init_hash(COLORREF *ColorTable, int noc) +{ + int i; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int nocolor = NUMELEMS(ctable); + color_p = nghash_init(nocolor); + nghash_unique(color_p, FALSE); + for (i = 0; i < nocolor; i++) { + strtolower(ctable[i].name); + ctable[i].rgbc = RGB(ctable[i].R, ctable[i].G, ctable[i].B); + nghash_insert(color_p, ctable[i].name, &(ctable[i].rgbc)); + } + + for (i = 0; i < noc; i++) { + (void) sprintf(buf, "color%d", i); + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) + (void) strcpy(colorstring, stdcolornames[i]); + COLORREF* val = (COLORREF*)nghash_find(color_p, colorstring); + if(val) + ColorTable[i] = *val; + else + ColorTable[i] = 0; + } +} + + +/* ColorTable[0]: background, ColorTable[1]: grid, text */ +void wincolor_init(COLORREF* ColorTable, int noc) +{ + int i; + static bool bgisblack = TRUE; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int nocolor = NUMELEMS(ctable); + + for (i = 0; i < nocolor; i++) { + strtolower(ctable[i].name); + ctable[i].rgbc = RGB(ctable[i].R, ctable[i].G, ctable[i].B); + } + i = 0; + while(i < noc) { + /* when color0 is set to white and color1 is not given, set ColorTable[2] to black */ + (void)sprintf(buf, "color%d", i); + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { + if (i == 1) { + /* switch the grid and text color depending on background */ + int tcolor = GetRValue(ColorTable[0]) + GetGValue(ColorTable[0]) + GetBValue(ColorTable[0]); + if (tcolor > 250) { + ColorTable[1] = RGB(0, 0, 0); + i++; + bgisblack = FALSE; + continue; + } + else { + ColorTable[1] = RGB(255, 255, 255); + i++; + bgisblack = TRUE; + continue; + } + } + /* old code: beginning with 12 the colors are repeated */ + else if (!bgisblack && (i == 12)) + (void)strcpy(colorstring, "black"); + else + (void)strcpy(colorstring, stdcolornames[i]); + } + ColorTable[i] = get_wincolor(colorstring, nocolor); + i++; + } +} + +void wincolor_redo(COLORREF* ColorTable, int noc) +{ + int i = 0; + static bool bgisblack = TRUE; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int nocolor = NUMELEMS(ctable); + + while (i < noc) { + /* when color0 is set to white and color1 is not given, set ColorTable[2] to black */ + (void)sprintf(buf, "color%d", i); + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { + if (i == 1) { + /* switch the grid and text color depending on background */ + int tcolor = GetRValue(ColorTable[0]) + GetGValue(ColorTable[0]) + GetBValue(ColorTable[0]); + if (tcolor > 250) { + ColorTable[1] = RGB(0, 0, 0); + i++; + bgisblack = FALSE; + continue; + } + else { + ColorTable[1] = RGB(255, 255, 255); + i++; + bgisblack = TRUE; + continue; + } + } + /* old code: beginning with 12 the colors are repeated */ + else if (!bgisblack && (i == 12)) + (void)strcpy(colorstring, "black"); + else + (void)strcpy(colorstring, stdcolornames[i]); + } + ColorTable[i] = get_wincolor(colorstring, nocolor); + i++; + } +} + +COLORREF *get_wincolor_hash(char *name) +{ + return nghash_find(color_p, name); +} + +static COLORREF get_wincolor(char *name, int nocolor) +{ + + int i; + for (i = 0; i < nocolor; i++) { + if (ciprefix(name, ctable[i].name)) { + return ctable[i].rgbc; + } + } + fprintf(stderr, "Warning: Color %s is not available\n", name); + fprintf(stderr, " Color 'green' is returned instead!\n"); + return RGB(0, 255, 0); +} + + diff --git a/src/frontend/wdisp/wincolor.h b/src/frontend/wdisp/wincolor.h new file mode 100644 index 000000000..e69de29bb From 0434b36074c33f61c3add5aed29d4566063cef5a Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 16:38:22 +0100 Subject: [PATCH 63/98] Restore original 'green', slight update on auto color selection vs. background --- src/frontend/wdisp/winprint.c | 159 +++++++++++++--------------- src/include/ngspice/wincolornames.h | 3 +- 2 files changed, 76 insertions(+), 86 deletions(-) diff --git a/src/frontend/wdisp/winprint.c b/src/frontend/wdisp/winprint.c index 4f8db2192..de07b1f3a 100644 --- a/src/frontend/wdisp/winprint.c +++ b/src/frontend/wdisp/winprint.c @@ -42,21 +42,23 @@ typedef tPrintData *tpPrintData; /* Zeiger darauf */ #define pPrintData(g) ((tpPrintData)(g->devdep)) /* externals */ -void WaitForIdle(void); /* Warte, bis keine Events da */ + +void WaitForIdle(void); /* wait until no events */ +extern void wincolor_init(COLORREF* ColorTable, int noc); /* lokale Variablen */ -static HFONT PlotFont = NULL; /* Font-Merker */ -static HFONT OldFont = NULL; -#define NumLines 7 /* Anzahl der LineStyles */ -static int LineTable[NumLines]; /* Speicher fuer die LineStyles */ -static HDC PrinterDC = NULL; /* Device Context */ -#define NumPrintColors 2 /* vordef. Farben */ -static COLORREF ColorTable[NumPrintColors];/* Speicher fuer die Farben */ -static int PrinterWidth = 1000; /* Breite des Papiers */ -static int PrinterHeight = 1000; /* Hoehe des Papiers */ +static HFONT PlotFont = NULL; +static HFONT OldFont = NULL; +#define NumLines 7 /* number of LineStyles */ +static int LineTable[NumLines]; /* LineStyle memory */ +static HDC PrinterDC = NULL; /* Device Context */ +#define NumPrintColors 23 /* number of pre-defined colors */ +static COLORREF ColorTable[NumPrintColors]; /* color memory */ +static int PrinterWidth = 1000; /* paper width */ +static int PrinterHeight = 1000; /* paper height */ /****************************************************************************** - Drucker-Initialisierung + printer initialization ******************************************************************************/ void WPRINT_PrintInit(HWND hwnd) @@ -156,39 +158,33 @@ int WPRINT_Init(void) pd.hSetupTemplate = NULL; /* Default-Drucker initialisieren */ - (void) PrintDlg(&pd); + (void) PrintDlg( &pd); /* Speicher freigeben */ - if (pd.hDevMode) { - GlobalFree(pd.hDevMode); - } - if (pd.hDevNames) { - GlobalFree(pd.hDevNames); - } + if( pd.hDevMode) GlobalFree( pd.hDevMode); + if( pd.hDevNames) GlobalFree( pd.hDevNames); /* DC holen */ PrinterDC = pd.hDC; if (!PrinterDC) return 1; /* Abmasze bestimmen */ - PrinterWidth = GetDeviceCaps(PrinterDC, HORZRES); - PrinterHeight = GetDeviceCaps(PrinterDC, VERTRES); - pWidth = GetDeviceCaps(PrinterDC, HORZSIZE); - pHeight = GetDeviceCaps(PrinterDC, VERTSIZE); + PrinterWidth = GetDeviceCaps( PrinterDC, HORZRES); + PrinterHeight = GetDeviceCaps( PrinterDC, VERTRES); + pWidth = GetDeviceCaps( PrinterDC, HORZSIZE); + pHeight = GetDeviceCaps( PrinterDC, VERTSIZE); /* Mapping Mode setzen (fuer Kreise) */ - if (pWidth > pHeight) { + if ( pWidth > pHeight) /* Querformat */ PrinterWidth = (PrinterHeight * pWidth) / pHeight; - } - else { + else /* Hochformat */ PrinterHeight = (PrinterWidth * pHeight) / pWidth; - } - SetMapMode(PrinterDC, MM_ISOTROPIC); - SetWindowExtEx(PrinterDC, PrinterWidth, PrinterHeight, NULL); - SetViewportExtEx(PrinterDC, PrinterWidth, PrinterHeight, NULL); + SetMapMode( PrinterDC, MM_ISOTROPIC); + SetWindowExtEx( PrinterDC, PrinterWidth, PrinterHeight, NULL); + SetViewportExtEx( PrinterDC, PrinterWidth, PrinterHeight, NULL); /* nicht hoeher als breit zeichnen */ if (pWidth < pHeight) { @@ -203,8 +199,7 @@ int WPRINT_Init(void) dispdev->numcolors = NumPrintColors; /* Farben initialisieren */ - ColorTable[0] = RGB(255,255,255); /* Weisz */ - ColorTable[1] = RGB(0, 0, 0); /* Schwarz */ + wincolor_init(ColorTable, NumPrintColors); /* LineStyles initialisieren */ LineTable[0] = PS_SOLID; @@ -217,16 +212,16 @@ int WPRINT_Init(void) /* Font */ if (!PlotFont) { - PlotFont = CreateFont(0,0,0,0, FW_DONTCARE, FALSE, FALSE, FALSE, + PlotFont = CreateFont( 0,0,0,0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH, NULL); } /* Abort-Prozedur setzen */ - SetAbortProc(PrinterDC, WPRINT_Abort); + SetAbortProc( PrinterDC, WPRINT_Abort); } /* fertig */ - return 0; + return (0); } @@ -239,14 +234,13 @@ int WPRINT_Init(void) int WPRINT_NewViewport(GRAPH * graph) { + TEXTMETRIC tm; tpPrintData pd; DOCINFO di; /* Parameter testen */ - if (!graph) { - return 1; - } + if (!graph) return 1; /* Initialisiere, falls noch nicht geschehen */ if (WPRINT_Init() != 0) { @@ -258,16 +252,15 @@ int WPRINT_NewViewport(GRAPH * graph) pd = calloc(1, sizeof(tPrintData)); if (!pd) return 1; graph->devdep = pd; - graph->n_byte_devdep = sizeof(tPrintData); /* Setze den Color-Index */ pd->ColorIndex = 0; /* Font setzen */ - OldFont = SelectObject(PrinterDC, PlotFont); + OldFont = SelectObject( PrinterDC, PlotFont); /* Font-Parameter abfragen */ - if (GetTextMetrics(PrinterDC, &tm)) { + if (GetTextMetrics( PrinterDC, &tm)) { graph->fontheight = tm.tmHeight; graph->fontwidth = tm.tmAveCharWidth; } @@ -286,28 +279,32 @@ int WPRINT_NewViewport(GRAPH * graph) graph->absolute.height = PrinterHeight; /* Druckauftrag anmelden */ - di.cbSize = sizeof(DOCINFO); + di.cbSize = sizeof( DOCINFO); di.lpszDocName = graph->plotname; di.lpszOutput = NULL; - if (StartDoc(PrinterDC, &di) <= 0) { - return 1; - } - if (StartPage(PrinterDC) <= 0) { - return 1; - } + if (StartDoc( PrinterDC, &di) <= 0) return 1; + if (StartPage( PrinterDC) <= 0) return 1; /* titel drucken */ if (graph->plotname) { UINT align; - align = GetTextAlign(PrinterDC); - SetTextAlign(PrinterDC, TA_RIGHT | TA_TOP | TA_NOUPDATECP); - TextOut(PrinterDC, PrinterWidth-graph->fontwidth, 1, graph->plotname, - (int) strlen(graph->plotname)); - SetTextAlign(PrinterDC, align); + align = GetTextAlign( PrinterDC); + SetTextAlign( PrinterDC, TA_RIGHT | TA_TOP | TA_NOUPDATECP); +#ifdef EXT_ASC + TextOut(PrinterDC, PrinterWidth - graph->fontwidth, 1, graph->plotname, + (int)strlen(graph->plotname)); +#else + wchar_t* wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->plotname) + 1); + MultiByteToWideChar(CP_UTF8, 0, graph->plotname, -1, wtext, 2 * strlen(graph->plotname) + 1); + TextOutW(PrinterDC, PrinterWidth - graph->fontwidth, 1, wtext, 2 * (int)strlen(graph->plotname) + 1); + tfree(wtext); +#endif + SetTextAlign( PrinterDC, align); } /* fertig */ - return 0; + return(0); } int WPRINT_Close(void) @@ -348,8 +345,6 @@ int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) /* Farben/Dicke */ ColIndex = pd->ColorIndex; - if (ColIndex > 1) - ColIndex = 1; MoveToEx(PrinterDC, x1, PrinterHeight - y1, NULL); NewPen = CreatePen( LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); @@ -380,18 +375,11 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) double dx0; double dy0; - if (!currentgraph) { - return 0; - } + if (!currentgraph) return 0; pd = pPrintData(currentgraph); - if (!pd) { - return 0; - } + if (!pd) return 0; ColIndex = pd->ColorIndex; - if (ColIndex > 1) { - ColIndex = 1; - } direction = AD_COUNTERCLOCKWISE; if (delta_theta < 0) { @@ -399,7 +387,7 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) delta_theta = - delta_theta; direction = AD_CLOCKWISE; } - SetArcDirection(PrinterDC, direction); + SetArcDirection( PrinterDC, direction); /* Geometrische Vorueberlegungen */ yb = PrinterHeight; @@ -411,17 +399,17 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) r = radius; dx0 = x0; dy0 = y0; - xs = (int) (dx0 + (r * cos(theta))); - ys = (int) (dy0 + (r * sin(theta))); - xe = (int) (dx0 + (r * cos(theta + delta_theta))); - ye = (int) (dy0 + (r * sin(theta + delta_theta))); + xs = (int)(dx0 + (r * cos(theta))); + ys = (int)(dy0 + (r * sin(theta))); + xe = (int)(dx0 + (r * cos(theta + delta_theta))); + ye = (int)(dy0 + (r * sin(theta + delta_theta))); /* Zeichnen */ - NewPen = CreatePen(LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); + NewPen = CreatePen( LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); OldPen = SelectObject(PrinterDC, NewPen); - Arc(PrinterDC, left, yb-top, right, yb-bottom, xs, yb-ys, xe, yb-ye); + Arc( PrinterDC, left, yb-top, right, yb-bottom, xs, yb-ys, xe, yb-ye); OldPen = SelectObject(PrinterDC, OldPen); - DeleteObject(NewPen); + DeleteObject( NewPen); return 0; } @@ -432,23 +420,24 @@ int WPRINT_Text(char * text, int x, int y, int degrees) int ColIndex; NG_IGNORE(degrees); - if (!currentgraph) { - return 0; - } + if (!currentgraph) return 0; pd = pPrintData(currentgraph); - if (!pd) { - return 0; - } + if (!pd) return 0; ColIndex = pd->ColorIndex; - if (ColIndex > 1) { - ColIndex = 1; - } - SetTextColor(PrinterDC, ColorTable[ColIndex]); - TextOut(PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, - text, (int) strlen(text)); - return 0; + SetTextColor( PrinterDC, ColorTable[ColIndex]); + +#ifdef EXT_ASC + TextOut(PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, text, (int)strlen(text)); +#else + wchar_t* wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(text) + 1); + MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, 2 * strlen(text) + 1); + TextOutW(PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, wtext, 2 * (int)strlen(text) + 1); + tfree(wtext); +#endif + return (0); } diff --git a/src/include/ngspice/wincolornames.h b/src/include/ngspice/wincolornames.h index 0ef62ec81..71fff4c9a 100644 --- a/src/include/ngspice/wincolornames.h +++ b/src/include/ngspice/wincolornames.h @@ -66,7 +66,7 @@ static struct colortable ctable[] = { 0, "Gold ",255,215, 0, 0, "GoldenRod ",218,165, 32, 0, "Gray ",127,127,127, - 0, "Green ", 0,128, 0, + 0, "Green ", 0,255, 0, 0, "GreenYellow ",173,255, 47, 0, "HoneyDew ",240,255,240, 0, "HotPink ",255,105,180, @@ -152,6 +152,7 @@ static struct colortable ctable[] = { 0, "Tomato ",255, 99, 71, 0, "Turquoise ", 64,224,208, 0, "Violet ",238,130,238, + 0, "WebGreen ", 0,128, 0, 0, "Wheat ",245,222,179, 0, "White ",255,255,255, 0, "WhiteSmoke ",245,245,245, From fadd70c4fa9ad9600e1ac33e50c73aa23d03c328 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 12 Jan 2020 16:56:03 +0100 Subject: [PATCH 64/98] enclose in WinGUI #ifdef --- src/frontend/wdisp/wincolor.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/frontend/wdisp/wincolor.c b/src/frontend/wdisp/wincolor.c index 7ca5abe29..7b5b361ce 100644 --- a/src/frontend/wdisp/wincolor.c +++ b/src/frontend/wdisp/wincolor.c @@ -4,6 +4,9 @@ #include "ngspice/ngspice.h" + +#ifdef HAS_WINGUI + #include "ngspice/cpextern.h" #include "ngspice/hash.h" #include "ngspice/macros.h" @@ -99,8 +102,9 @@ void wincolor_redo(COLORREF* ColorTable, int noc) if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { if (i == 1) { /* switch the grid and text color depending on background */ - int tcolor = GetRValue(ColorTable[0]) + GetGValue(ColorTable[0]) + GetBValue(ColorTable[0]); - if (tcolor > 250) { + int tcolor = GetRValue(ColorTable[0]) + + (int)(1.5 * GetGValue(ColorTable[0])) + GetBValue(ColorTable[0]); + if (tcolor > 360) { ColorTable[1] = RGB(0, 0, 0); i++; bgisblack = FALSE; @@ -143,4 +147,4 @@ static COLORREF get_wincolor(char *name, int nocolor) return RGB(0, 255, 0); } - +#endif From 15398870062ab06af65623be96cea94f63643091 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 13 Jan 2020 23:11:01 +0100 Subject: [PATCH 65/98] color input for text/grids (color1), background (color0) and graphs (color2-22) on Windows via set color2=red set color2=rgb:ff/0/0 set color2=rgbd:255,0,0 several examples given in the example files --- examples/utf-8/стекло/ext-utf8-2.cir | 6 +-- examples/utf-8/стекло/ext-utf8-c.cir | 2 +- examples/utf-8/стекло/ext-utf8-c2.cir | 59 ++++++++++++++++++++++ src/frontend/wdisp/wincolor.c | 70 +++++++++++++++++++++++++-- 4 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 examples/utf-8/стекло/ext-utf8-c2.cir diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index 53f2072dc..e12d0cb08 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -1,10 +1,10 @@ * test de titré .control set hcopydevtype = postscript -set hcopypscolor=25 +set hcopypscolor=18 set hcopypstxcolor=21 set hcopyscale=1 -set color2=rgb:F/0/0 +set color2=rgb:FF/0/0 setcs hcopyfont=Arial set hcopyfontsize=18 @@ -18,8 +18,6 @@ setcs xfont='Noto Sans Chinese' set gridwidth=4 set xbrushwidth=1 -hardcopy - plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" diff --git a/examples/utf-8/стекло/ext-utf8-c.cir b/examples/utf-8/стекло/ext-utf8-c.cir index 4ee9ec66b..149977a56 100644 --- a/examples/utf-8/стекло/ext-utf8-c.cir +++ b/examples/utf-8/стекло/ext-utf8-c.cir @@ -1,4 +1,4 @@ -* test de titré +titré 'test of various color inputs for background, text/grid and graphs 1' .control set hcopydevtype = postscript set hcopypscolor=25 diff --git a/examples/utf-8/стекло/ext-utf8-c2.cir b/examples/utf-8/стекло/ext-utf8-c2.cir new file mode 100644 index 000000000..08eea2af8 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-c2.cir @@ -0,0 +1,59 @@ +* titré 'test of various color inputs for background, text/grid and graphs 2' +.control +set hcopydevtype = postscript +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 +*set color2=rgb:F/0/0 + +setcs hcopyfont=Arial +set hcopyfontsize=18 + + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans' +*set xfont_size=18 + +set gridwidth=4 +set xbrushwidth=1 +set color0=white +*set color2=brown +set color2=rgbd:255/0/0 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +set color0=black +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +set color0=Blue +set color1=Yellow +set color2=rgb:00/FF/00 +set gridwidth=1 +set xbrushwidth=4 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +unset color1 +set color0=MediumBlue +set color2=Magenta +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=GreenYellow +set color2=rgbd:128/128/75 +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=black +set color2=pink +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +*shell gv plot_5.ps & + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/src/frontend/wdisp/wincolor.c b/src/frontend/wdisp/wincolor.c index 7b5b361ce..d5382c84c 100644 --- a/src/frontend/wdisp/wincolor.c +++ b/src/frontend/wdisp/wincolor.c @@ -43,7 +43,57 @@ void wincolor_init_hash(COLORREF *ColorTable, int noc) ColorTable[i] = 0; } } +/* evaluate rgb:0/FF/F0 rgb:0/F/0 rgbd:295/0/128 */ +static COLORREF get_wincolor_rgb(char *costr) +{ + char *tmpstr; + if (ciprefix("rgb:", costr)) { + char *t1, *t2, *t3; + tmpstr = costr + 4; + if (tmpstr) { + t1 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t2 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t3 = copy(tmpstr); + if (t1 && t2 && t3) { + int c1, c2, c3; + c1 = (int) strtol(t1, NULL, 16); + c2 = (int) strtol(t2, NULL, 16); + c3 = (int) strtol(t3, NULL, 16); + tfree(t1); + tfree(t2); + tfree(t3); + return RGB(c1, c2, c3); + } + } + } + else if (ciprefix("rgbd:", costr)) { + char *t1, *t2, *t3; + tmpstr = costr + 5; + if (tmpstr) { + t1 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t2 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t3 = copy(tmpstr); + if (t1 && t2 && t3) { + int c1, c2, c3; + c1 = (int) strtol(t1, NULL, 10); + c2 = (int) strtol(t2, NULL, 10); + c3 = (int) strtol(t3, NULL, 10); + tfree(t1); + tfree(t2); + tfree(t3); + return RGB(c1, c2, c3); + } + } + } + + fprintf(stderr, "Error: Cannot detect color in string %s, setting Web Green\n", costr); + return RGB(0, 128, 0); +} /* ColorTable[0]: background, ColorTable[1]: grid, text */ void wincolor_init(COLORREF* ColorTable, int noc) @@ -64,8 +114,9 @@ void wincolor_init(COLORREF* ColorTable, int noc) if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { if (i == 1) { /* switch the grid and text color depending on background */ - int tcolor = GetRValue(ColorTable[0]) + GetGValue(ColorTable[0]) + GetBValue(ColorTable[0]); - if (tcolor > 250) { + int tcolor = GetRValue(ColorTable[0]) + + (int)(1.5 * GetGValue(ColorTable[0])) + GetBValue(ColorTable[0]); + if (tcolor > 360) { ColorTable[1] = RGB(0, 0, 0); i++; bgisblack = FALSE; @@ -84,6 +135,11 @@ void wincolor_init(COLORREF* ColorTable, int noc) else (void)strcpy(colorstring, stdcolornames[i]); } + else if (ciprefix("rgb", colorstring)){ + ColorTable[i] = get_wincolor_rgb(colorstring); + i++; + continue; + } ColorTable[i] = get_wincolor(colorstring, nocolor); i++; } @@ -97,7 +153,10 @@ void wincolor_redo(COLORREF* ColorTable, int noc) int nocolor = NUMELEMS(ctable); while (i < noc) { - /* when color0 is set to white and color1 is not given, set ColorTable[2] to black */ + /* when color0 is set to white and color1 is not given, set text and grid color + as ColorTable[1] to black, when color0 is any other color, select black or + white text and grid color according to a weighted value derived from color0. + This selection is a compromise based on visibility.*/ (void)sprintf(buf, "color%d", i); if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { if (i == 1) { @@ -123,6 +182,11 @@ void wincolor_redo(COLORREF* ColorTable, int noc) else (void)strcpy(colorstring, stdcolornames[i]); } + else if (ciprefix("rgb", colorstring)) { + ColorTable[i] = get_wincolor_rgb(colorstring); + i++; + continue; + } ColorTable[i] = get_wincolor(colorstring, nocolor); i++; } From 001c1060cc8d2313bf1c1e10a7d9e96512995723 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 2 Feb 2020 10:43:54 +0100 Subject: [PATCH 66/98] use a more pleasant color for ps background --- examples/utf-8/стекло/있어요/ext-utf8-3.cir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir index ec84e4730..621dc4657 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-3.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -1,7 +1,7 @@ * test de titré .control set hcopydevtype = postscript -set hcopypscolor=5 +set hcopypscolor=1 set hcopypstxcolor=21 set hcopyscale=1 set color2=rgb:F/0/0 From 01dda37f969b6acff069d6617979a2fd0aee32c7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 2 Feb 2020 12:06:42 +0100 Subject: [PATCH 67/98] allow disabling UNICODE by --disable-utf8, which sets the pre-processor flag EXT_ASC --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index 215ac59aa..9aaf51cc2 100644 --- a/configure.ac +++ b/configure.ac @@ -91,6 +91,10 @@ AC_ARG_WITH([tcl], AC_ARG_WITH([ngshared], [AS_HELP_STRING([--with-ngshared], [Compiles ngspice as shared library (dll)])]) +# --disable-utf8: don't use utf-8 and tchar for string representation, UNICODE support disabled +AC_ARG_ENABLE([utf8], + [AS_HELP_STRING([--disable-utf8], [Don't use utf-8 or tchar (default is UNICODE support with utf-8)])]) + # old options, not maintained, may even not work at all # --enable-ansi: try to force --ansi option to the compiler @@ -971,6 +975,10 @@ if test "x$enable_smltmsdebug" = xyes; then AC_DEFINE([D_DBG_SMALLTIMES], [], [Define if we want debug distortion analysis (SMALLTIMES)]) AC_MSG_RESULT([WARNING: Distortion analysis debug *D_DBG_SMALLTIMES* is enabled]) fi +if test "x$enable_utf8" = xno; then + AC_DEFINE([EXT_ASC], [], [Define if you want to disable UNICODE support]) + AC_MSG_RESULT([WARNING: UNICOPDE support is disabled, extended ascii is enabled instead]) +fi AC_PROG_YACC AC_PATH_PROG([BISON], [bison]) From 2ef62c934d99ad5a3d5a01ac521c1ca9b1802952 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 7 Feb 2020 22:42:45 +0100 Subject: [PATCH 68/98] cp_getvar: force a limit to a string entered Issue a warning, truncate the string --- src/frontend/variable.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 5883b4c0a..0f0818ef4 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -729,12 +729,12 @@ cp_getvar(char *name, enum cp_types type, void *retval, size_t rsize) case CP_STRING: { /* Gotta be careful to have room. */ char *s = cp_unquote(v->va_string); cp_wstrip(s); - if (strlen(s) >= rsize - 1) { - fprintf(stderr, "Internal Error: string length for variable %s is limited to %zu chars\n", v->va_name, rsize); - controlled_exit(EXIT_BAD); + if (strlen(s) > rsize) { + fprintf(stderr, "Warning: string length for variable %s is limited to %zu chars\n", v->va_name, rsize); + /* limit the string length */ + s[rsize] = '\0'; } - else - strcpy((char*) retval, s); + strcpy((char*) retval, s); tfree(s); break; } From 7d9062f1f9607bf0f0018e995fd2f098f7d772d6 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 7 Feb 2020 22:44:36 +0100 Subject: [PATCH 69/98] add variable ticchar, allow an arbitrary character as ticmark --- src/frontend/plotting/graf.c | 18 ++++++------------ src/include/ngspice/graph.h | 1 + 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index e5fde6f95..29fd2b9e3 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -120,6 +120,10 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ } } + if (!cp_getvar("ticchar", CP_STRING, graph->ticchar, 1)) { + strcpy(graph->ticchar, "X"); + } + if (cp_getvar("ticlist", CP_LIST, ticlist, 0)) { wl = vareval("ticlist"); ticlist = wl_flatten(wl); @@ -300,26 +304,16 @@ void gr_point(struct dvec *dv, if ((tics = currentgraph->ticdata) != NULL) { for (; *tics < HUGE; tics++) if (*tics == (double) np) { - DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2), + DevDrawText(currentgraph->ticchar, (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); - /* gr_redraw will redraw this w/o our having to save it - Guenther Roehrich 22-Jan-99 */ - /* SaveText(currentgraph, "x", - (int) (tox - currentgraph->fontwidth / 2), - (int) (toy - currentgraph->fontheight / 2)); */ break; } } else if ((currentgraph->ticmarks >0) && (np > 0) && (np % currentgraph->ticmarks == 0)) { /* Draw an 'x' */ - DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2), + DevDrawText(currentgraph->ticchar, (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); - /* gr_redraw will redraw this w/o our having to save it - Guenther Roehrich 22-Jan-99 */ - /* SaveText(currentgraph, "x", - (int) (tox - currentgraph->fontwidth / 2), - (int) (toy - currentgraph->fontheight / 2)); */ } break; case PLOT_COMB: diff --git a/src/include/ngspice/graph.h b/src/include/ngspice/graph.h index b682f377f..2fd05471d 100644 --- a/src/include/ngspice/graph.h +++ b/src/include/ngspice/graph.h @@ -61,6 +61,7 @@ struct graph { int ticmarks; /* mark every ticmark'th point */ double *ticdata; + char ticchar[2]; int fontwidth, fontheight; /* for use in grid */ PLOTTYPE plottype; /* defined in FTEconstant.h */ From 9f73552d295322e864bc9eb3adb3a4426bc5f6fb Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 7 Feb 2020 23:17:24 +0100 Subject: [PATCH 70/98] new variable nolegend: with 'set nolegend' plotting of the legend is suppressed. --- examples/utf-8/стекло/있어요/ext-utf8-3.cir | 2 ++ src/frontend/plotting/graf.c | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir index 621dc4657..aa6305b8e 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-3.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -18,6 +18,8 @@ setcs xfont='Noto Sans CJK JP Medium' set gridwidth=4 set xbrushwidth=1 +set nolegend + *hardcopy **plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 29fd2b9e3..cbefaa1bc 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -423,9 +423,9 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) /* Put the legend entry on the screen. */ - drawlegend(currentgraph, cur.plotno++, dv); -} /* end of function gr_start_internal */ - + if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) + drawlegend(currentgraph, cur.plotno++, dv); +} /* Start one plot of a graph */ @@ -599,7 +599,8 @@ void gr_redraw(GRAPH *graph) cur.plotno = 0; for (link = graph->plotdata; link; link = link->next) { /* redraw legend */ - drawlegend(graph, cur.plotno++, link->vector); + if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) + drawlegend(graph, cur.plotno++, link->vector); /* replot data if onevalue, pass it a NULL scale From 1c834c8bf3c7e7cd2b3bc73e89d554b4cae11656 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 9 Feb 2020 14:33:29 +0100 Subject: [PATCH 71/98] enable color and font selection for X11: Add graphics context gridgc for plotting the grids. Enable rgbd:, input of color by RGB 0 ... 255 If no color1 (text/grid) is given, select black or white according to backgrund color. Error message, but no crash if font cannot be selected. Enable separate linewidth selection for grid and graph. --- src/frontend/plotting/x11.c | 159 ++++++++++++++++++++++++++---------- 1 file changed, 115 insertions(+), 44 deletions(-) diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index f8b3d1676..b84bf034d 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -67,7 +67,8 @@ typedef struct x11info { int isopen; Widget shell, form, view, buttonbox, buttons[2]; XFontStruct *font; - GC gc; + GC gc; /* graphics context for graphs */ + GC gridgc; /* graphics context for grid, linewidth may differ */ int lastx, lasty; /* used in X_DrawLine */ int lastlinestyle; /* used in X_DrawLine */ Pixel colors[NUMCOLORS]; @@ -181,12 +182,6 @@ X11_Init(void) X11_Open = 1; - /* "invert" works better than "xor" for B&W */ - - /* xor gc should be a function of the pixels that are written on */ - /* gcvalues.function = GXxor; */ - /* this patch makes lines visible on true color displays - Guenther Roehrich 22-Jan-99 */ gcvalues.function = GXinvert; gcvalues.line_width = 1; gcvalues.foreground = 1; @@ -224,10 +219,15 @@ initlinestyles(void) } +/* initialize color selection for grid/text, background and graphs. + Input is by setting the variables color0 (background), color1 + (grid/text) and color%id with %id from2 to 19. color%id may be set + to color name string or rgb:0/FF/F0 rgb:0/F/0 rgbd:295/0/128 */ static void initcolors(GRAPH *graph) { int i; + bool gridgiven = TRUE; static char *colornames[] = { "black", /* white */ "white", "red", "blue", "orange", "green", "pink", @@ -238,7 +238,7 @@ initcolors(GRAPH *graph) "yellow", "" }; - XColor visualcolor, exactcolor; + XColor visualcolor, exactcolor, bgcolor; char buf[BSIZE_SP], colorstring[BSIZE_SP]; int xmaxcolors = NUMCOLORS; /* note: can we get rid of this? */ @@ -257,15 +257,41 @@ initcolors(GRAPH *graph) for (i = 0; i < xmaxcolors; i++) { (void) sprintf(buf, "color%d", i); - if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { (void) strcpy(colorstring, colornames[i]); -#ifdef HAVE_LIBXFT - /* text color info for xft */ - if (i == 1) - strncpy(DEVDEP(graph).txtcolor, colorstring, 15); - else if (i == 0) - strncpy(DEVDEP(graph).bgcolor, colorstring, 15); -#endif + if(i == 1) + gridgiven = FALSE; + } + /* colorstring by integer numbers between 0 and 255 */ + else if (ciprefix("rgbd:", colorstring)) { + char *t1, *t2, *t3, *tmpstr; + tmpstr = colorstring + 5; + if (tmpstr) { + t1 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t2 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t3 = copy(tmpstr); + if (t1 && t2 && t3) { + double c1, c2, c3; + c1 = strtol(t1, NULL, 10) / 255.; + c2 = strtol(t2, NULL, 10) / 255.; + c3 = strtol(t3, NULL, 10) / 255.; + c1 = fmax(0., fmin(c1, 1.)); + c2 = fmax(0., fmin(c2, 1.)); + c3 = fmax(0., fmin(c3, 1.)); + tfree(t1); + tfree(t2); + tfree(t3); + sprintf(colorstring, "RGBi:%.3f/%.3f/%.3f", c1, c2, c3); + } + else { + fprintf(cp_err, "Error: Could not evaluate color%d", i); + continue; + } + } + } + if (!XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)), colorstring, &visualcolor, &exactcolor)) { @@ -277,21 +303,32 @@ initcolors(GRAPH *graph) : WhitePixel(display, DefaultScreen(display)); continue; } - DEVDEP(graph).colors[i] = visualcolor.pixel; - - /* MW. I don't need this, everyone must know what he is doing - if (i > 0 && - DEVDEP(graph).colors[i] == DEVDEP(graph).view->core.background_pixel) { - DEVDEP(graph).colors[i] = DEVDEP(graph).colors[0]; - } */ - + if (i == 0) { + bgcolor = visualcolor; + strncpy(DEVDEP(graph).bgcolor, colorstring, 15); + } + if ((!gridgiven) && (i == 1)) { + /* select grid color according to background color. + Empirical selection using the color depth of the background */ + /* switch the grid and text color depending on background */ + int tcolor = (int)bgcolor.red + (int)(1.5 * bgcolor.green) + (int)bgcolor.blue; + if (tcolor > 92160) { + DEVDEP(graph).colors[1] = BlackPixel(display, DefaultScreen(display)); + strncpy(DEVDEP(graph).txtcolor, "black", 15); + } + else { + DEVDEP(graph).colors[1] = WhitePixel(display, DefaultScreen(display)); + strncpy(DEVDEP(graph).txtcolor, "white", 15); + } + } + else { + DEVDEP(graph).colors[i] = visualcolor.pixel; + if (i == 1) + strncpy(DEVDEP(graph).txtcolor, colorstring, 15); + } } /* MW. Set Beackgroound here */ XSetWindowBackground(display, DEVDEP(graph).window, DEVDEP(graph).colors[0]); - - /* if (DEVDEP(graph).colors[0] != DEVDEP(graph).view->core.background_pixel) { - DEVDEP(graph).colors[0] = DEVDEP(graph).view->core.background_pixel; - } */ } for (i = xmaxcolors; i < NUMCOLORS; i++) { @@ -384,6 +421,7 @@ X11_NewViewport(GRAPH *graph) Cursor cursor; XSetWindowAttributes w_attrs; XGCValues gcvalues; + XGCValues gridgcvalues; static Arg formargs[ ] = { { XtNleft, (XtArgVal) XtChainLeft }, @@ -495,7 +533,13 @@ X11_NewViewport(GRAPH *graph) DEVDEP(graph).font->max_bounds.descent + 1; #else int wl, wh; - Xget_str_length("ABCD", &wl, &wh, NULL, fontname, xfont_size); + int ret = Xget_str_length("ABCD", &wl, &wh, NULL, fontname, xfont_size); + if (ret == 1) + ret = Xget_str_length("我能吞下", &wl, &wh, NULL, fontname, xfont_size); + if (ret == 1) { + fprintf(cp_err, "Error: Could not establish a font for %s\n", fontname); + return 1; + } graph->fontwidth = (int)(wl / 4); graph->fontheight = wh; DEVDEP(graph).fsize = xfont_size; @@ -509,17 +553,29 @@ X11_NewViewport(GRAPH *graph) XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, &w_attrs); - /* have to note font and set mask GCFont in XCreateGC, p.w.h. */ - gcvalues.line_width = MW_LINEWIDTH; - gcvalues.cap_style = CapNotLast; - gcvalues.function = GXcopy; + int linewidth, gridwidth; + if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) + gcvalues.line_width = MW_LINEWIDTH; + else + gcvalues.line_width = linewidth; + if (!cp_getvar("gridwidth", CP_NUM, &gridwidth, 0)) + gridgcvalues.line_width = MW_LINEWIDTH; + else + gridgcvalues.line_width = gridwidth; + gridgcvalues.cap_style = gcvalues.cap_style = CapNotLast; + gridgcvalues.function = gcvalues.function = GXcopy; #ifndef HAVE_LIBXFT - gcvalues.font = DEVDEP(graph).font->fid; + gridgcvalues.font = gcvalues.font = DEVDEP(graph).font->fid; DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + DEVDEP(graph).gridgc = XCreateGC(display, DEVDEP(graph).window, + GCFont | GCLineWidth | GCCapStyle | GCFunction, &gridgcvalues); #else DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + DEVDEP(graph).gridgc = XCreateGC(display, DEVDEP(graph).window, + GCLineWidth | GCCapStyle | GCFunction, &gridgcvalues); + #endif /* should absolute.positions really be shell.pos? */ graph->absolute.xpos = DEVDEP(graph).view->core.x; @@ -570,13 +626,19 @@ X11_Close(void) int X11_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { - NG_IGNORE(isgrid); if (DEVDEP(currentgraph).isopen) - XDrawLine(display, DEVDEP(currentgraph).window, + if (isgrid) { + XDrawLine(display, DEVDEP(currentgraph).window, + DEVDEP(currentgraph).gridgc, + x1, currentgraph->absolute.height - y1, + x2, currentgraph->absolute.height - y2); + } + else { + XDrawLine(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x1, currentgraph->absolute.height - y1, x2, currentgraph->absolute.height - y2); - + } return 0; } @@ -611,8 +673,6 @@ X11_Text(char *text, int x, int y, int angle) /* We specify text position by lower left corner, so have to adjust for X11's font nonsense. */ - NG_IGNORE(angle); - int wlen = 0, wheight = 0; #ifndef HAVE_LIBXFT @@ -659,6 +719,7 @@ int X11_DefineXft(GRAPH *graph) XftResult rot_result; XftPattern *rot_pat = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ DEVDEP(graph).font0 = XftFontOpenPattern(display, rot_pat); + if(DEVDEP(graph).font0 == NULL) { fprintf(stderr, "Can't load font pattern %s\n", DEVDEP(graph).fname); } @@ -727,11 +788,14 @@ X11_SetLinestyle(int linestyleid) } XChangeGC(display, DEVDEP(currentgraph).gc, GCLineStyle, &values); - + XChangeGC(display, DEVDEP(currentgraph).gridgc, GCLineStyle, &values); currentgraph->linestyle = linestyleid; XSetDashes(display, DEVDEP(currentgraph).gc, 0, xlinestyles[linestyleid], 4); + + XSetDashes(display, DEVDEP(currentgraph).gridgc, 0, + xlinestyles[linestyleid], 4); } return 0; @@ -744,6 +808,8 @@ X11_SetColor(int colorid) currentgraph->currentcolor = colorid; XSetForeground(display, DEVDEP(currentgraph).gc, DEVDEP(currentgraph).colors[colorid]); + XSetForeground(display, DEVDEP(currentgraph).gridgc, + DEVDEP(currentgraph).colors[colorid]); return 0; } @@ -1030,6 +1096,7 @@ void RemoveWindow(GRAPH *graph) XFreeFont(display, DEVDEP(graph).font); #endif XFreeGC(display, DEVDEP(graph).gc); + XFreeGC(display, DEVDEP(graph).gridgc); #ifdef HAVE_LIBXFT XftFontClose( display, DEVDEP(graph).font0); XftFontClose( display, DEVDEP(graph).font90); @@ -1247,11 +1314,15 @@ Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* fonam XftPatternAddString(ext_pat, XFT_FAMILY, foname); XftPatternAddDouble(ext_pat, XFT_PIXEL_SIZE, (double)fsize); XftResult ext_result; - hfont = gfont = XftFontOpenPattern(display, XftFontMatch(display, 0, ext_pat, &ext_result)); - XftTextExtentsUtf8(display, gfont, (XftChar8 *)text, strlen(text), &extents); + XftPattern *font_pat = XftFontMatch(display, 0, ext_pat, &ext_result); + hfont = gfont = XftFontOpenPattern(display, font_pat); XftPatternDestroy(ext_pat); } - XftTextExtentsUtf8( display, gfont, (XftChar8 *)text, strlen(text), &extents ); + if(gfont) + XftTextExtentsUtf8( display, gfont, (XftChar8 *)text, strlen(text), &extents ); + else { + return 1; + } if(hfont) XftFontClose( display,hfont); @@ -1269,7 +1340,7 @@ X11_GetLenStr(GRAPH *gr, char* instring) Xget_str_length(instring, &wl, &wh, NULL, DEVDEP(gr).fname, DEVDEP(gr).fsize); return wl; } -#endif +#endif #else From 10a4c231c649afa02512bc90a137a9906898a7df Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 9 Feb 2020 14:39:14 +0100 Subject: [PATCH 72/98] examle file for color and font selection --- .clang-format | 107 -------------------------- examples/utf-8/стекло/ext-utf8-c4.cir | 31 ++++++++ 2 files changed, 31 insertions(+), 107 deletions(-) delete mode 100644 .clang-format create mode 100644 examples/utf-8/стекло/ext-utf8-c4.cir diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 553942d86..000000000 --- a/.clang-format +++ /dev/null @@ -1,107 +0,0 @@ -# Initially made using -# clang-format -style=llvm -dump-config > .clang-format -# Then lines were modified to get the desired results -# -# Incorporate these options by adding the flag -style=file -# and putting this file in the directory of the file being formatted or -# one of its parent directories -# -# See http://clang.llvm.org/docs/ClangFormat.html for usage and -# http://clang.llvm.org/docs/ClangFormatStyleOptions.html for options -# ---- -Language: Cpp -# BasedOnStyle: LLVM -AccessModifierOffset: 0 -AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlinesLeft: false -AlignOperands: false -AlignTrailingComments: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: false -BinPackArguments: true -BinPackParameters: true -BreakBeforeBraces: Custom -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: true - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: true - IndentBraces: false -BreakAfterJavaFieldAnnotations: false -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Custom -BreakBeforeTernaryOperators: false -BreakConstructorInitializersBeforeComma: false -BreakStringLiterals: true -ColumnLimit: 78 -CommentPragmas: '^ IWYU pragma:' # not sure what this should be -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 8 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IncludeCategories: # need to consider more - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - - Regex: '^(<|"(gtest|isl|json)/)' - Priority: 3 - - Regex: '.*' - Priority: 1 -IncludeIsMainRegex: '$' -IndentCaseLabels: true -IndentWidth: 4 -IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 4 -NamespaceIndentation: None -ObjCBlockIndentWidth: 2 # Not applicable (N/A) -ObjCSpaceAfterProperty: false # N/A -ObjCSpaceBeforeProtocolList: true # N/A -PenaltyBreakBeforeFirstCallParameter: 19 # 19 was the original value -PenaltyBreakComment: 300 # 300 was the original value -PenaltyBreakFirstLessLess: 120 # 120 was the original value -PenaltyBreakString: 1000 # 1000 was the original value -PenaltyExcessCharacter: 10000000 # 1000000 was the original value -PenaltyReturnTypeOnItsOwnLine: 60 # 60 was the original value -PointerAlignment: Right -ReflowComments: true -SortIncludes: true -SpaceAfterCStyleCast: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInContainerLiterals: true # N/A -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 8 # N/A since not using tabs -UseTab: Never -# ... generated by the command here. Not sure why - diff --git a/examples/utf-8/стекло/ext-utf8-c4.cir b/examples/utf-8/стекло/ext-utf8-c4.cir new file mode 100644 index 000000000..29c50c0b5 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-c4.cir @@ -0,0 +1,31 @@ +* titré 'test of various color inputs for background, text/grid and graphs 4' +* to figure out the available font names, run the command +* 'fc-list | cut -f2 -d: | sort -u | less -r > fonts-avail.txt' +.control + +let x = vector(5) +let y = exp(x) + +*setcs xfont='Baekmuk Dotum' +setcs xfont='Noto Sans CJK JP' +*set xfont_size=18 + +set gridwidth=1 +set xbrushwidth=8 +set color2=rgbd:0/126/0 +set color0=blue +* color1 (text/grid) selected automatically +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +set color2=rgbd:0/0/255 +set color1=rgb:0/0/0 +set color0=white +set xbrushwidth=4 +set gridwidth=2 +set nolegend +plot y vs x xlabel '나는 유리를 먹을 수 있어요' ylabel 'それは私を傷つけません' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc From e90393b7049464e4da2e3ae645977c2c508c1692 Mon Sep 17 00:00:00 2001 From: Vogt Date: Mon, 10 Feb 2020 17:21:46 +0100 Subject: [PATCH 73/98] Set the color tables and linewidths personal for each graph, added to strucht graph Use only these data for plotting. If zooming a plot windows, set as an extra parameter the graph id of the 'mother graph'. Copy its color and line data to the new graph. This is done by an extra parameter sgraphid to the internal plot command that is issued in fcn PlotWindowProc(). Thus zooming will keep the background, text/line and graph colors. Function setcolor() will always look into the colorarray of the current graph. --- src/frontend/display.c | 4 +- src/frontend/display.h | 2 +- src/frontend/hpgl.c | 4 +- src/frontend/plotting/graf.c | 38 ++++++++++++++---- src/frontend/plotting/graf.h | 3 +- src/frontend/plotting/graphdb.c | 1 + src/frontend/plotting/grid.c | 18 ++++----- src/frontend/plotting/plot5.c | 4 +- src/frontend/plotting/plotit.c | 19 ++++++++- src/frontend/plotting/x11.c | 2 +- src/frontend/postsc.c | 11 ++--- src/frontend/wdisp/wincolor.c | 9 +++++ src/frontend/wdisp/windisp.c | 71 +++++++++++++++++++++++++-------- src/include/ngspice/ftedev.h | 2 +- src/include/ngspice/graph.h | 10 +++++ 15 files changed, 150 insertions(+), 48 deletions(-) diff --git a/src/frontend/display.c b/src/frontend/display.c index 54595883f..797cd0103 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -275,9 +275,9 @@ SetLinestyle(int linestyleid) void -SetColor(int colorid) +SetColor(int colorid, GRAPH *graph) { - dispdev->SetColor (colorid); + dispdev->SetColor (colorid, graph); } diff --git a/src/frontend/display.h b/src/frontend/display.h index a3ff68d4b..df7944d21 100644 --- a/src/frontend/display.h +++ b/src/frontend/display.h @@ -23,7 +23,7 @@ void DevDrawText(char *text, int x, int y, int angle); void DefineColor(int colorid, double red, double green, double blue); void DefineLinestyle(int linestyleid, int mask); void SetLinestyle(int linestyleid); -void SetColor(int colorid); +void SetColor(int colorid, GRAPH* graph); void DevUpdate(void); void DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny); void Input(REQUEST *request, RESPONSE *response); diff --git a/src/frontend/hpgl.c b/src/frontend/hpgl.c index 9b700b1ff..77be5e6d1 100644 --- a/src/frontend/hpgl.c +++ b/src/frontend/hpgl.c @@ -291,9 +291,9 @@ int GL_SetLinestyle(int linestyleid) } -/* ARGSUSED */ -int GL_SetColor(int colorid) +int GL_SetColor(int colorid, GRAPH* graph) { + NG_IGNORE(graph); fprintf(plotfile, "SP %d;", colorid); return 0; diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index cbefaa1bc..8732c108b 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -80,6 +80,7 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ int xtype, int ytype, /* The types of the data graphed. */ const char *pname, const char *commandline) /* For xi_zoomdata() */ + int prevgraph) /* plot id, if started from a previous plot*/ { GRAPH *graph; wordlist *wl; @@ -154,6 +155,16 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ graph->plotname = tprintf("%s: %s", pname, plotname); + + /* restore background color from previous graph, e.g. for zooming, + it will be used in NewViewport(graph) */ + if (prevgraph > 0) { + graph->mgraphid = prevgraph; + } + else { + graph->mgraphid = 0; + } + /* note: have enum here or some better convention */ if (NewViewport(graph) == 1) { /* note: where is the error message generated? */ @@ -162,6 +173,19 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ return (FALSE); } + /* restore data from previous graph, e.g. for zooming */ + if (prevgraph > 0) { + int i; + GRAPH* pgraph = FindGraph(prevgraph); + /* transmit colors */ + for (i = 0; i < 25; i++) { + graph->colorarray[i] = pgraph->colorarray[i]; + } + strcpy(graph->ticchar, pgraph->ticchar); + graph->ticdata = pgraph->ticdata; + graph->ticmarks = pgraph->ticmarks; + } + /* layout decisions */ /* note: have to do before gr_fixgrid and after NewViewport */ graph->viewportxoff = graph->fontwidth * 8; /* 8 lines on left */ @@ -290,7 +314,7 @@ void gr_point(struct dvec *dv, return; } } - SetColor(dv->v_color); + SetColor(dv->v_color, currentgraph); switch (currentgraph->plottype) { double *tics; @@ -463,7 +487,7 @@ void drawlegend(GRAPH *graph, int plotno, struct dvec *dv) const int y = graph->absolute.height - graph->fontheight - ((plotno + 2) / 2) * (graph->fontheight); const int i = y + graph->fontheight / 2 + 1; - SetColor(dv->v_color); + SetColor(dv->v_color, graph); if (graph->plottype == PLOT_POINT) { char buf[16]; (void) sprintf(buf, "%c : ", dv->v_linestyle); @@ -473,10 +497,10 @@ void drawlegend(GRAPH *graph, int plotno, struct dvec *dv) SetLinestyle(dv->v_linestyle); DevDrawLine(x, i, x + graph->viewport.width / 20, i, FALSE); } - SetColor(1); - DevDrawText(dv->v_name, x_base + graph->fontwidth, y, 0); -} /* end of function drawlegend */ - + SetColor(1, graph); + DevDrawText(dv->v_name, x + graph->viewport.width / 20 + + graph->fontwidth, y, 0); +} /* end one plot of a graph */ @@ -627,7 +651,7 @@ void gr_restoretext(GRAPH *graph) /* restore text */ for (k = graph->keyed; k; k = k->next) { - SetColor(k->colorindex); + SetColor(k->colorindex, graph); DevDrawText(k->text, k->x, k->y, 0); } } diff --git a/src/frontend/plotting/graf.h b/src/frontend/plotting/graf.h index 9d73c5cab..d960a3b14 100644 --- a/src/frontend/plotting/graf.h +++ b/src/frontend/plotting/graf.h @@ -19,7 +19,8 @@ int gr_init(double *xlims, double *ylims, const char *xlabel, const char *ylabel, /* Labels for axes. */ int xtype, int ytype, - const char *pname, const char *commandline); + const char *pname, const char *commandline, + int prevgraph); void gr_point(struct dvec *dv, double newx, double newy, double oldx, double oldy, int np); diff --git a/src/frontend/plotting/graphdb.c b/src/frontend/plotting/graphdb.c index 861721ecf..4ca5cf432 100644 --- a/src/frontend/plotting/graphdb.c +++ b/src/frontend/plotting/graphdb.c @@ -60,6 +60,7 @@ GRAPH *NewGraph(void) LISTGRAPH *list; const int BucketId = RunningId % NUMGBUCKETS; + /* allocate memory for graph via LISTGRAPH */ if ((list = TMALLOC(LISTGRAPH, 1)) == NULL) { internalerror("can't allocate a listgraph"); return (GRAPH *) NULL; diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c index 6342a5e83..d8a57e5c8 100644 --- a/src/frontend/plotting/grid.c +++ b/src/frontend/plotting/grid.c @@ -74,7 +74,7 @@ gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype) if (graph->grid.gridtype == GRID_NONE) graph->grid.gridtype = GRID_LIN; - SetColor(1); + SetColor(1, graph); SetLinestyle(1); if ((graph->data.xmin > graph->data.xmax) || @@ -132,7 +132,7 @@ void gr_redrawgrid(GRAPH *graph) { - SetColor(1); + SetColor(1, graph); SetLinestyle(1); /* draw labels */ if (graph->grid.xlabel) { @@ -1477,7 +1477,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d /* Let's be lazy and just draw everything -- we won't get called too * much and the circles get clipped anyway... */ - SetColor(18); + SetColor(18, graph); cliparc((double) (centx + xoffset + radoff - rad), (double) (centy + yoffset), rad, 2*angle, @@ -1491,7 +1491,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d M_PI - 2 * angle, centx, centy, maxrad, 0); /* Draw the upper and lower circles. */ - SetColor(19); + SetColor(19, graph); aclip = cliparc((double) (centx + xoffset + radoff), (double) (centy + yoffset + irad), irad, (double) (M_PI * 1.5 + 2 * iangle), @@ -1500,7 +1500,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d xlab = (int)(centx + xoffset + radoff + irad * cos(aclip)); ylab = (int)(centy + yoffset + irad * (1 + sin(aclip))); if ((ylab - gr_ycenter) > graph->fontheight) { - SetColor(1); + SetColor(1, graph); adddeglabel(graph, pdeg, xlab, ylab, gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); /* @@ -1508,7 +1508,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d adddeglabel(graph, ndeg, xlab, ylab, gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); */ - SetColor(19); + SetColor(19, graph); } } aclip = cliparc((double) (centx + xoffset + radoff), @@ -1519,14 +1519,14 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d if ((aclip >= 0 && aclip < 2*M_PI - M_PI/180) && (pdeg < 359)) { xlab = (int)(centx + xoffset + radoff + irad * cos(aclip)); ylab = (int)(centy + yoffset + irad * (sin(aclip) - 1)); - SetColor(1); + SetColor(1, graph); adddeglabel(graph, ndeg, xlab, ylab, gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); - SetColor(19); + SetColor(19, graph); } /* Now toss the labels on... */ - SetColor(1); + SetColor(1, graph); x = centx + xoffset + (int)radoff - 2 * (int)rad - gi_fntwidth * (int) strlen(plab) - 2; diff --git a/src/frontend/plotting/plot5.c b/src/frontend/plotting/plot5.c index cc3aeec47..155a089bb 100644 --- a/src/frontend/plotting/plot5.c +++ b/src/frontend/plotting/plot5.c @@ -210,9 +210,11 @@ int Plt5_SetLinestyle(int linestyleid) /* ARGSUSED */ -int Plt5_SetColor(int colorid) + +int Plt5_SetColor(int colorid, GRAPH *graph) { NG_IGNORE(colorid); + NG_IGNORE(graph); /* do nothing */ return 0; diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index 2d3d1bf5c..5bf27ada3 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -275,6 +275,14 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) return FALSE; } + /* All these things are static so that "samep" will work. + static double *xcompress = NULL, *xindices = NULL; + static double *xlim = NULL, *ylim = NULL, *xynull; + static double *xdelta = NULL, *ydelta = NULL; + static char *xlabel = NULL, *ylabel = NULL, *title = NULL; + static double *xprevgraph = NULL;*/ + + int prevgraph = 0; static bool nointerp = FALSE; static GRIDTYPE gtype = GRID_LIN; static PLOTTYPE ptype = PLOT_LIN; @@ -324,6 +332,8 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) nxlabel = getword(wwl, "xlabel"); nylabel = getword(wwl, "ylabel"); ntitle = getword(wwl, "title"); + /* remove sgraphid */ + txfee(getlims(wwl, "sgraphid", 1)); /* Build the plot command. This construction had been done with wordlists * and reversing, and flattening, but it is clearer as well as much more @@ -426,6 +436,13 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) txfree(getlims(wl, "ydel", 1)); } + if (!sameflag || !xprevgraph) { + xprevgraph = getlims(wl, "sgraphid", 1); + if(xprevgraph) + prevgraph = (int)(*xprevgraph); + } else { + txfree(getlims(wl, "sgraphid", 1)); + } /* Get the grid type and the point type. Note we can't do if-else * here because we want to catch all the grid types. */ @@ -1122,7 +1139,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, gtype, ptype, xlabel, ylabel, xt, y_type, - plot_cur->pl_typename, ds_get_buf(&ds_cline))) { + plot_cur->pl_typename, ds_get_buf(&ds_cline), prevgraph)) { goto quit; } diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index b84bf034d..2e3b24886 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -354,7 +354,7 @@ handlekeypressed(Widget w, XtPointer client_data, XEvent *ev, Boolean *continue_ /* write it */ PushGraphContext(graph); text[nbytes] = '\0'; - SetColor(1); + SetColor(1, graph); DevDrawText(text, keyev->x, graph->absolute.height - keyev->y, 0); /* save it */ SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y); diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index f0eaad0c0..ec07a60eb 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -410,12 +410,12 @@ int PS_Text(char *text, int x, int y, int angle) PS_SetLinestyle(SOLID); /* set text color to black if background is not white */ if (setbgcolor > 0) - PS_SetColor(0); + PS_SetColor(0, currentgraph); else - PS_SetColor(1); + PS_SetColor(1, currentgraph); /* if color is given by set hcopytxpscolor=settxcolor, give it a try */ if (settxcolor >= 0) - PS_SetColor(settxcolor); + PS_SetColor(settxcolor, currentgraph); /* stroke the path if there's an open one */ PS_Stroke(); /* move to (x, y) */ @@ -431,7 +431,7 @@ int PS_Text(char *text, int x, int y, int angle) /* restore old linestyle */ - PS_SetColor(savedcolor); + PS_SetColor(savedcolor, currentgraph); PS_SetLinestyle(savedlstyle); return 0; } @@ -458,8 +458,9 @@ int PS_SetLinestyle(int linestyleid) } -int PS_SetColor(int colorid) +int PS_SetColor(int colorid, GRAPH *graph) { + NG_IGNORE(graph); PS_LinestyleColor(currentgraph->linestyle, colorid); return 0; } diff --git a/src/frontend/wdisp/wincolor.c b/src/frontend/wdisp/wincolor.c index d5382c84c..de53318cf 100644 --- a/src/frontend/wdisp/wincolor.c +++ b/src/frontend/wdisp/wincolor.c @@ -13,6 +13,7 @@ #undef BOOLEAN #include #include "ngspice/wincolornames.h" +#include "ngspice/graph.h" @@ -145,6 +146,14 @@ void wincolor_init(COLORREF* ColorTable, int noc) } } +void wincolor_graph(COLORREF* ColorTable, int noc, GRAPH *graph) +{ + int i; + for (i = 0; i < noc; i++) { + graph->colorarray[i] = ColorTable[i]; + } +} + void wincolor_redo(COLORREF* ColorTable, int noc) { int i = 0; diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 98fa313c7..7ed7d576d 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -4,6 +4,7 @@ * Holger Vogt 07.12.01 * Holger Vogt 05.12.07 * Holger Vogt 01.11.18 + * Holger Vogt 09.02.20 */ #include "ngspice/ngspice.h" @@ -64,6 +65,7 @@ extern HWND swString; /* string input window of main window */ extern int DevSwitch(char *devname); extern int NewViewport(GRAPH *pgraph); extern void com_hardcopy(wordlist *wl); +extern void wincolor_graph(COLORREF* ColorTable, int noc, GRAPH* graph); /* defines */ #define RAD_TO_DEG (180.0 / M_PI) @@ -349,6 +351,19 @@ static LRESULT PrintInit(HWND hwnd) return 0; } +/* check if background color is dark enough. + Threshold is empirical by looking at color tables */ +static bool get_black(GRAPH* graph) +{ + int tcolor = GetRValue(graph->colorarray[0]) + + (int)(1.5 * GetGValue(graph->colorarray[0])) + + GetBValue(graph->colorarray[0]); + if (tcolor > 360) { + return FALSE; + } + else + return TRUE; +} /* window procedure */ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, @@ -395,14 +410,16 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, /* left mouse button: connect coordinate pair by dashed pair of x, y lines */ if (wParam & MK_LBUTTON) { hdc = GetDC(hwnd); - if (isblack) { + GRAPH* gr = pGraph(hwnd); + isblack = get_black(gr); + if (isblack) prevmix = SetROP2(hdc, R2_XORPEN); } else { prevmix = SetROP2(hdc, R2_NOTXORPEN); } /* Create white dashed pen */ - NewPen = CreatePen(LType(12), 0, ColorTable[1]); + NewPen = CreatePen(LType(12), 0, gr->colorarray[1]); OldPen = SelectObject(hdc, NewPen); /* draw lines with previous coodinates -> delete old line because of XOR */ MoveToEx (hdc, x0, y0, NULL); @@ -427,12 +444,14 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, /* right mouse button: create white (black) dashed box */ else if (wParam & MK_RBUTTON) { hdc = GetDC (hwnd); + GRAPH* gr = pGraph(hwnd); + isblack = get_black(gr); if (isblack) prevmix = SetROP2(hdc, R2_XORPEN); else prevmix = SetROP2(hdc, R2_NOTXORPEN); /* Create white (black) dashed pen */ - NewPen = CreatePen(LType(12), 0, ColorTable[1]); + NewPen = CreatePen(LType(12), 0, gr->colorarray[1]); OldPen = SelectObject(hdc, NewPen); /* draw box with previous coodinates -> delete old lines because of XOR */ MoveToEx (hdc, x0, y0, NULL); @@ -535,11 +554,11 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, // "setplot %s; %s xlimit %e %e ylimit %e %e; setplot $curplot\n", - "setplot %s; %s xlimit %e %e ylimit %e %e\n", - buf2, gr->commandline, fx0, fxe, fy0, fye); + "setplot %s; %s xlimit %e %e ylimit %e %e sgraphid %d\n", + buf2, gr->commandline, fx0, fxe, fy0, fye, gr->graphid); } else { - (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", - gr->commandline, fx0, fxe, fy0, fye); + (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e sgraphid %d\n", + gr->commandline, fx0, fxe, fy0, fye, gr->graphid); } (void) cp_evloop(buf); @@ -635,6 +654,7 @@ int WIN_NewViewport(GRAPH *graph) #endif tpWindowData wd; HMENU sysmenu; + GRAPH* pgraph = NULL; /* test the parameters */ if (!graph) { @@ -647,6 +667,16 @@ int WIN_NewViewport(GRAPH *graph) return 1; } + /* get the colors into graph struct */ + wincolor_graph(ColorTable, NumWinColors, graph); + /* If we had a previous graph, e.g. after zooming, we + have to set the background color already here, because + background is set below */ + if (graph->mgraphid > 0) { + pgraph = FindGraph(graph->mgraphid); + graph->colorarray[0] = pgraph->colorarray[0]; + } + /* allocate device dependency info */ wd = calloc(1, sizeof(tWindowData)); if (!wd) { @@ -685,7 +715,7 @@ int WIN_NewViewport(GRAPH *graph) /* set the background color */ SelectObject(dc, GetStockObject(DC_BRUSH)); - SetDCBrushColor(dc, ColorTable[0]); + SetDCBrushColor(dc, graph->colorarray[0]); wd->wnd = window; SetWindowLongPtr(window, 0, (LONG_PTR)graph); @@ -696,9 +726,6 @@ int WIN_NewViewport(GRAPH *graph) /* get the mask */ GetClientRect(window, &(wd->Area)); - - - /* set the Color Index */ wd->ColorIndex = 0; @@ -715,7 +742,7 @@ int WIN_NewViewport(GRAPH *graph) AppendMenu(sysmenu, MF_STRING, ID_HARDCOPY_BW, STR_HARDCOPY_BW); /* set default parameters of DC */ - SetBkColor(dc, ColorTable[0]); + SetBkColor(dc, graph->colorarray[0]); SetBkMode(dc, TRANSPARENT ); /* set font */ @@ -748,6 +775,10 @@ int WIN_NewViewport(GRAPH *graph) linewidth = 0; if (linewidth < 0) linewidth = 0; + if (pgraph) + graph->graphwidth = pgraph->graphwidth; + else + graph->graphwidth = linewidth; /* get linewidth information from .spiceinit or .control section */ if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) @@ -755,6 +786,11 @@ int WIN_NewViewport(GRAPH *graph) if (gridlinewidth < 0) gridlinewidth = 0; + if (pgraph) + graph->gridwidth = pgraph->gridwidth; + else + graph->gridwidth = gridlinewidth; + /* wait until the window is really there */ WaitForIdle(); @@ -828,9 +864,9 @@ WIN_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) MoveToEx(wd->hDC, x1, wd->Area.bottom - y1, NULL); if (isgrid) - NewPen = CreatePen(LType(wd->ColorIndex), gridlinewidth, ColorTable[wd->ColorIndex]); + NewPen = CreatePen(LType(wd->ColorIndex), currentgraph->gridwidth, currentgraph->colorarray[wd->ColorIndex]); else - NewPen = CreatePen(LType(wd->ColorIndex), linewidth, ColorTable[wd->ColorIndex]); + NewPen = CreatePen(LType(wd->ColorIndex), currentgraph->graphwidth, currentgraph->colorarray[wd->ColorIndex]); OldPen = SelectObject(wd->hDC, NewPen); LineTo(wd->hDC, x2, wd->Area.bottom - y2); OldPen = SelectObject(wd->hDC, OldPen); @@ -889,7 +925,7 @@ int WIN_Arc(int x0, int y0, int radius, double theta, double delta_theta) ye = (int)(dy0 + (r * sin(theta + delta_theta))); /* plot */ - NewPen = CreatePen(LType(wd->ColorIndex), linewidth, ColorTable[wd->ColorIndex]); + NewPen = CreatePen(LType(wd->ColorIndex), linewidth, currentgraph->colorarray[wd->ColorIndex]); OldPen = SelectObject(wd->hDC, NewPen); Arc(wd->hDC, left, yb-top, right, yb-bottom, xs, yb-ys, xe, yb-ye); OldPen = SelectObject(wd->hDC, OldPen); @@ -1002,7 +1038,7 @@ int WIN_Text(char *text, int x, int y, int angle) #endif SelectObject(wd->hDC, hfont); - SetTextColor(wd->hDC, ColorTable[wd->ColorIndex]); + SetTextColor(wd->hDC, currentgraph->colorarray[wd->ColorIndex]); #ifdef EXT_ASC TextOut(wd->hDC, x, wd->Area.bottom - y - currentgraph->fontheight, text, (int)strlen(text)); #else @@ -1043,8 +1079,9 @@ int WIN_SetLinestyle(int style) } -int WIN_SetColor(int color) +int WIN_SetColor(int color, GRAPH *graph) { + NG_IGNORE(graph); tpWindowData wd; if (!currentgraph) diff --git a/src/include/ngspice/ftedev.h b/src/include/ngspice/ftedev.h index f378b5a0a..530f497ac 100644 --- a/src/include/ngspice/ftedev.h +++ b/src/include/ngspice/ftedev.h @@ -24,7 +24,7 @@ typedef int disp_fn_Text_t (char *text, int x, int y, int angle); typedef int disp_fn_DefineColor_t (int colorid, double red, double green, double blue); typedef int disp_fn_DefineLinestyle_t (int linestyleid, int mask); typedef int disp_fn_SetLinestyle_t (int linestyleid); -typedef int disp_fn_SetColor_t (int colorid); +typedef int disp_fn_SetColor_t (int colorid, GRAPH *graf); typedef int disp_fn_Update_t (void); typedef int disp_fn_Track_t (void); typedef int disp_fn_MakeMenu_t (void); diff --git a/src/include/ngspice/graph.h b/src/include/ngspice/graph.h index 2fd05471d..e7b64d615 100644 --- a/src/include/ngspice/graph.h +++ b/src/include/ngspice/graph.h @@ -105,6 +105,16 @@ struct graph { /* for zoomin */ char *commandline; + /* colors used */ + unsigned long colorarray[25]; + + /* we have a mother graph */ + int mgraphid; + + /* linewidths */ + int graphwidth; + int gridwidth; + /* Space here is allocated by NewViewport and de-allocated by DestroyGraph. */ From 0d4fe21269936d2d0232971a957730a8023ef7c0 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 10 Feb 2020 21:17:31 +0100 Subject: [PATCH 74/98] examples for the recent plot enhancements --- examples/utf-8/стекло/ext-utf8-c4.cir | 4 +++- examples/utf-8/стекло/있어요/ext-utf8-2.cir | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/examples/utf-8/стекло/ext-utf8-c4.cir b/examples/utf-8/стекло/ext-utf8-c4.cir index 29c50c0b5..a2bdabaa6 100644 --- a/examples/utf-8/стекло/ext-utf8-c4.cir +++ b/examples/utf-8/стекло/ext-utf8-c4.cir @@ -8,12 +8,14 @@ let y = exp(x) *setcs xfont='Baekmuk Dotum' setcs xfont='Noto Sans CJK JP' -*set xfont_size=18 +*setcs xfont='맑은 고딕' +set xfont_size=20 set gridwidth=1 set xbrushwidth=8 set color2=rgbd:0/126/0 set color0=blue +unset nolegend * color1 (text/grid) selected automatically plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' set color2=rgbd:0/0/255 diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2.cir b/examples/utf-8/стекло/있어요/ext-utf8-2.cir index 45b073d54..ca1971862 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-2.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-2.cir @@ -8,7 +8,10 @@ set hcopydevtype = postscript set hcopypscolor=0 set hcopypstxcolor=1 set hcopyscale=1 +* 16 bit color for Linux set color2=rgb:F/0/0 +* 256 bit color for Windows or Linux +set color2=rgb:FF/0/0 *setcs hcopyfont=Arial * *setcs hcopyfont='Nimbus Mono-Regular' @@ -28,11 +31,18 @@ plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜ * Linux, CYGWIN * Use font (*.ttc) from Cygwin distribution setcs xfont='Noto Sans CJK JP Light' -set xfont_size=16 +set xfont_size=16 +set color2=rgb:0/FF/0 +set xbrushwidth=2 plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 22 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +set color2=rgb:0/FF/FF +set xbrushwidth=4 plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 23 私はガラスを食べられます。それは私を傷つけません' loglog +set color2=rgbd:255/0/255 +set xbrushwidth=8 plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog - +unset color2 +set color0=white * https://www.fontsc.com/font/tag/arabic setcs xfont='Lateef' set xfont_size=22 From f1972850ecf626b01ed89a9568a3192c593ea303 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 12 Feb 2020 21:17:41 +0100 Subject: [PATCH 75/98] switch to colorarray in graph to string all color data, one set per each graph. If we are zooming or selecting a cutout, copy the source graph's colors to the new graph. Transfer the old graphs id to the new graph via graph->graphid. --- src/frontend/plotting/x11.c | 87 ++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 2e3b24886..370b3bdb6 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -151,7 +151,6 @@ X11_Init(void) XGCValues gcvalues; - /* grrr, Xtk forced contortions */ char *argv[2]; int argc = 2; @@ -245,11 +244,11 @@ initcolors(GRAPH *graph) if (numdispplanes == 1) { /* black and white */ xmaxcolors = 2; - DEVDEP(graph).colors[0] = DEVDEP(graph).view->core.background_pixel; - if (DEVDEP(graph).colors[0] == WhitePixel(display, DefaultScreen(display))) - DEVDEP(graph).colors[1] = BlackPixel(display, DefaultScreen(display)); + graph->colorarray[0] = DEVDEP(graph).view->core.background_pixel; + if (graph->colorarray[0] == WhitePixel(display, DefaultScreen(display))) + graph->colorarray[1] = BlackPixel(display, DefaultScreen(display)); else - DEVDEP(graph).colors[1] = WhitePixel(display, DefaultScreen(display)); + graph->colorarray[1] = WhitePixel(display, DefaultScreen(display)); } else { if (numdispplanes < NXPLANES) @@ -298,7 +297,7 @@ initcolors(GRAPH *graph) (void) sprintf(ErrorMessage, "can't get color %s\n", colorstring); externalerror(ErrorMessage); - DEVDEP(graph).colors[i] = i ? BlackPixel(display, + graph->colorarray[i] = i ? BlackPixel(display, DefaultScreen(display)) : WhitePixel(display, DefaultScreen(display)); continue; @@ -313,26 +312,24 @@ initcolors(GRAPH *graph) /* switch the grid and text color depending on background */ int tcolor = (int)bgcolor.red + (int)(1.5 * bgcolor.green) + (int)bgcolor.blue; if (tcolor > 92160) { - DEVDEP(graph).colors[1] = BlackPixel(display, DefaultScreen(display)); + graph->colorarray[1] = BlackPixel(display, DefaultScreen(display)); strncpy(DEVDEP(graph).txtcolor, "black", 15); } else { - DEVDEP(graph).colors[1] = WhitePixel(display, DefaultScreen(display)); + graph->colorarray[1] = WhitePixel(display, DefaultScreen(display)); strncpy(DEVDEP(graph).txtcolor, "white", 15); } } else { - DEVDEP(graph).colors[i] = visualcolor.pixel; + graph->colorarray[i] = visualcolor.pixel; if (i == 1) strncpy(DEVDEP(graph).txtcolor, colorstring, 15); } } - /* MW. Set Beackgroound here */ - XSetWindowBackground(display, DEVDEP(graph).window, DEVDEP(graph).colors[0]); } for (i = xmaxcolors; i < NUMCOLORS; i++) { - DEVDEP(graph).colors[i] = DEVDEP(graph).colors[i + 1 - xmaxcolors]; + graph->colorarray[i] = graph->colorarray[i + 1 - xmaxcolors]; } } @@ -422,6 +419,7 @@ X11_NewViewport(GRAPH *graph) XSetWindowAttributes w_attrs; XGCValues gcvalues; XGCValues gridgcvalues; + GRAPH *pgraph = NULL; static Arg formargs[ ] = { { XtNleft, (XtArgVal) XtChainLeft }, @@ -553,15 +551,34 @@ X11_NewViewport(GRAPH *graph) XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, &w_attrs); - int linewidth, gridwidth; + int linewidth, gridlinewidth; + /* If we had a previous graph, e.g. after zooming, we + have to set the background color already here, because + background is set below */ + if (graph->mgraphid > 0) { + pgraph = FindGraph(graph->mgraphid); + } + /* get linewidth information from .spiceinit or .control section */ if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) - gcvalues.line_width = MW_LINEWIDTH; + linewidth = MW_LINEWIDTH; + if (linewidth < 0) + linewidth = MW_LINEWIDTH; + if (pgraph) + gcvalues.line_width = graph->graphwidth = pgraph->graphwidth; else - gcvalues.line_width = linewidth; - if (!cp_getvar("gridwidth", CP_NUM, &gridwidth, 0)) - gridgcvalues.line_width = MW_LINEWIDTH; + gcvalues.line_width = graph->graphwidth = linewidth; + + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = MW_LINEWIDTH; + if (gridlinewidth < 0) + gridlinewidth = MW_LINEWIDTH; + + if (pgraph) + gridgcvalues.line_width = graph->gridwidth = pgraph->gridwidth; else - gridgcvalues.line_width = gridwidth; + gridgcvalues.line_width = graph->gridwidth = gridlinewidth; + gridgcvalues.cap_style = gcvalues.cap_style = CapNotLast; gridgcvalues.function = gcvalues.function = GXcopy; #ifndef HAVE_LIBXFT @@ -586,6 +603,15 @@ X11_NewViewport(GRAPH *graph) initlinestyles(); initcolors(graph); + /* we have a 'mother' graph and want to get its colors */ + int i; + if(pgraph) { + for(i = 0; i < 25; i++) + graph->colorarray[i] = pgraph->colorarray[i]; + } + + XSetWindowBackground(display, DEVDEP(graph).window, graph->colorarray[0]); + /* set up cursor */ cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); @@ -738,7 +764,16 @@ int X11_DefineXft(GRAPH *graph) Colormap cmap = DefaultColormap(display, 0); XftColor color; - XftColorAllocName(display, DefaultVisual(display, 0), cmap, DEVDEP(graph).txtcolor, &color); + XRenderColor rcolor; + XColor xxcolor; + /* pixel -> XColor -> XftColor */ + xxcolor.pixel = graph->colorarray[1]; + XQueryColor(display, cmap, &xxcolor); + rcolor.alpha = 65535; + rcolor.red = xxcolor.red; + rcolor.green = xxcolor.green; + rcolor.blue = xxcolor.blue; + XftColorAllocValue(display, DefaultVisual(display, 0), cmap, &rcolor, &color); DEVDEP(graph).color = color; DEVDEP(graph).cmap = cmap; DEVDEP(graph).draw = XftDrawCreate( @@ -803,13 +838,13 @@ X11_SetLinestyle(int linestyleid) int -X11_SetColor(int colorid) +X11_SetColor(int colorid, GRAPH *graph) { currentgraph->currentcolor = colorid; XSetForeground(display, DEVDEP(currentgraph).gc, - DEVDEP(currentgraph).colors[colorid]); + currentgraph->colorarray[colorid]); XSetForeground(display, DEVDEP(currentgraph).gridgc, - DEVDEP(currentgraph).colors[colorid]); + currentgraph->colorarray[colorid]); return 0; } @@ -1010,12 +1045,12 @@ zoomin(GRAPH *graph) if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, - "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e; setplot $curplot\n", - buf2, graph->commandline, fx0, fx1, fy0, fy1); + "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e sgraphid %d; setplot $curplot\n", + buf2, graph->commandline, fx0, fx1, fy0, fy1, graph->graphid); } else { /* set the foreground and background colors to the "calling" window's colors */ - (void) sprintf(buf, "set color0=%s; set color1=%s; %s xlimit %e %e ylimit %e %e\n", - DEVDEP(graph).bgcolor, DEVDEP(graph).txtcolor, graph->commandline, fx0, fx1, fy0, fy1); + (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e sgraphid %d\n", + graph->commandline, fx0, fx1, fy0, fy1, graph->graphid); } /* don't use the following if using GNU Readline or BSD EditLine */ From b153b7699c9d945ff726598511780c382808a4b5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 16 Feb 2020 11:52:59 +0100 Subject: [PATCH 76/98] some missing brackets, typos --- src/frontend/plotting/graf.c | 4 ++-- src/frontend/plotting/plotit.c | 11 +++-------- src/frontend/wdisp/windisp.c | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 8732c108b..8e2ab37e6 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -79,7 +79,7 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ const char *ylabel, /* Labels for axes. */ int xtype, int ytype, /* The types of the data graphed. */ const char *pname, - const char *commandline) /* For xi_zoomdata() */ + const char *commandline, /* For xi_zoomdata() */ int prevgraph) /* plot id, if started from a previous plot*/ { GRAPH *graph; @@ -762,7 +762,7 @@ static int iplot(struct plot *pl, int id) (void) gr_init(xlims, ylims, xs->v_name, pl->pl_title, NULL, n_vec_plot, 0.0, 0.0, GRID_LIN, PLOT_LIN, xs->v_name, yl, xs->v_type, yt, - plot_cur->pl_typename, commandline); + plot_cur->pl_typename, commandline, 0); for (v = pl->pl_dvecs; v; v = v->v_next) { if (v->v_flags & VF_PLOT) { diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index 5bf27ada3..6de95aafd 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -275,14 +275,9 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) return FALSE; } - /* All these things are static so that "samep" will work. - static double *xcompress = NULL, *xindices = NULL; - static double *xlim = NULL, *ylim = NULL, *xynull; - static double *xdelta = NULL, *ydelta = NULL; - static char *xlabel = NULL, *ylabel = NULL, *title = NULL; - static double *xprevgraph = NULL;*/ - + static double *xprevgraph = NULL; int prevgraph = 0; + static bool nointerp = FALSE; static GRIDTYPE gtype = GRID_LIN; static PLOTTYPE ptype = PLOT_LIN; @@ -333,7 +328,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) nylabel = getword(wwl, "ylabel"); ntitle = getword(wwl, "title"); /* remove sgraphid */ - txfee(getlims(wwl, "sgraphid", 1)); + txfree(getlims(wwl, "sgraphid", 1)); /* Build the plot command. This construction had been done with wordlists * and reversing, and flattening, but it is clearer as well as much more diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 7ed7d576d..8ea6824d2 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -412,7 +412,7 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, hdc = GetDC(hwnd); GRAPH* gr = pGraph(hwnd); isblack = get_black(gr); - if (isblack) + if (isblack) { prevmix = SetROP2(hdc, R2_XORPEN); } else { From f5fa14b390f3d48a903c37c69fe8f9274554b7d7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 16 Feb 2020 12:27:04 +0100 Subject: [PATCH 77/98] some more examples, use $oscompiled --- examples/utf-8/стекло/ext-utf8-3.cir | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 examples/utf-8/стекло/ext-utf8-3.cir diff --git a/examples/utf-8/стекло/ext-utf8-3.cir b/examples/utf-8/стекло/ext-utf8-3.cir new file mode 100644 index 000000000..d1b46d0e9 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-3.cir @@ -0,0 +1,66 @@ +* test de titré +* set oscompiled nn [0..8] +* nn: Other MINGW Cygwin FreeBSD OpenBSD Solaris Linux macOS Visual_Studio +* all text snippets (nonsense text) from http://kermitproject.org/utf8.html + +.control +set hcopydevtype = postscript +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 +if $oscompiled = 8 + set color2=rgb:FF/0/0 +else + set color2=rgb:F/0/0 +endif +setcs hcopyfont=Arial +set hcopyfontsize=18 + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans' +*set xfont_size=18 + +set gridwidth=4 +set xbrushwidth=1 + +*hardcopy + +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +if $oscompiled = 6 + shell export LC_CTYPE ="de_DE.UTF-8" +endif +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +set gridwidth=1 +set xbrushwidth=4 + +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +if $oscompiled = 6 + shell export LC_CTYPE ="de_DE.UTF-8" +endif +gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +if $oscompiled = 8 or $oscompiled = 1 + shell Start /B plot_5.ps +else + shell gv plot_5.ps & +endif + +*wrdata test.out y vs x +*asciiplot atest.out y vs x + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc From e595347819bca182895cb6835b932902d828c04e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 16 Feb 2020 13:50:08 +0100 Subject: [PATCH 78/98] remove the remains of the old xgraph program that has not been supported for many years --- src/frontend/Makefile.am | 2 - src/frontend/commands.c | 9 -- src/frontend/plotting/Makefile.am | 5 +- src/frontend/plotting/gnuplot.c | 1 - src/frontend/plotting/plotit.c | 14 --- src/frontend/plotting/xgraph.c | 167 ------------------------------ src/frontend/plotting/xgraph.h | 13 --- visualc/vngspice.vcxproj | 1 - 8 files changed, 2 insertions(+), 210 deletions(-) delete mode 100644 src/frontend/plotting/xgraph.c delete mode 100644 src/frontend/plotting/xgraph.h diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index 46000d289..2ebd79e19 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -69,8 +69,6 @@ libfte_la_SOURCES = \ com_sysinfo.c \ com_unset.c \ com_unset.h \ - com_xgraph.c \ - com_xgraph.h \ completion.h \ control.h \ control.c \ diff --git a/src/frontend/commands.c b/src/frontend/commands.c index be8d8e394..119bd1dcc 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -47,7 +47,6 @@ #include "com_let.h" #include "com_plot.h" #include "com_setscale.h" -#include "com_xgraph.h" #include "com_gnuplot.h" #include "com_state.h" #include "com_chdir.h" @@ -205,10 +204,6 @@ struct comm spcp_coms[] = { { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, NULL, "varname ... : Perform matrix transposition on multi-D vectors." } , - { "xgraph", com_xgraph, FALSE, TRUE, - { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, - NULL, - "file plotargs : Send plot to Xgraph-11." } , { "gnuplot", com_gnuplot, FALSE, TRUE, { 1, 041000, 041000, 041000 }, E_DEFHMASK, 2, LOTS, NULL, @@ -689,10 +684,6 @@ struct comm nutcp_coms[] = { { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, NULL, "varname ... : Perform matrix transposition on multi-D vectors." } , - { "xgraph", com_xgraph, FALSE, TRUE, - { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, - NULL, - "file plotargs : Send plot to Xgraph-11." } , { "gnuplot", com_gnuplot, FALSE, TRUE, { 1, 041000, 041000, 041000 }, E_DEFHMASK, 2, LOTS, NULL, diff --git a/src/frontend/plotting/Makefile.am b/src/frontend/plotting/Makefile.am index 055cb75d3..d641bd116 100644 --- a/src/frontend/plotting/Makefile.am +++ b/src/frontend/plotting/Makefile.am @@ -26,9 +26,8 @@ libplotting_la_SOURCES = \ if !NO_X libplotting_la_SOURCES += \ x11.c \ - x11.h \ - xgraph.c \ - xgraph.h + x11.h + endif AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend @X_CFLAGS@ diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index 9672af6cd..9420a31aa 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -1,5 +1,4 @@ /********** - * From xgraph.c: * Copyright 1992 Regents of the University of California. All rights reserved. * Author: 1992 David A. Gates, U. C. Berkeley CAD Group * diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index 6de95aafd..997ada184 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -13,7 +13,6 @@ #include "plotit.h" #include "points.h" #include "agraf.h" -#include "xgraph.h" #include "gnuplot.h" #include "graf.h" @@ -1073,19 +1072,6 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) y_type = d ? SV_NOTYPE : vecs->v_type; -#ifndef X_DISPLAY_MISSING - if (devname && eq(devname, "xgraph")) { - /* Interface to XGraph-11 Plot Program */ - ft_xgraph(xlims, ylims, hcopy, - title ? title : vecs->v_plot->pl_title, - xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type), - ylabel ? ylabel : ft_typabbrev(y_type), - gtype, ptype, vecs); - rtn = TRUE; - goto quit; - } -#endif - if (devname && eq(devname, "gnuplot")) { /* Interface to Gnuplot Plot Program */ ft_gnuplot(xlims, ylims, hcopy, diff --git a/src/frontend/plotting/xgraph.c b/src/frontend/plotting/xgraph.c deleted file mode 100644 index ff40075bd..000000000 --- a/src/frontend/plotting/xgraph.c +++ /dev/null @@ -1,167 +0,0 @@ -/********** -Copyright 1992 Regents of the University of California. All rights reserved. -Author: 1992 David A. Gates, U. C. Berkeley CAD Group -**********/ - -/* - * Xgraph-11 plots. - */ - -#include "ngspice/ngspice.h" -#include "ngspice/cpdefs.h" -#include "ngspice/ftedefs.h" -#include "ngspice/dvec.h" -#include "ngspice/fteparse.h" -#include "xgraph.h" - - -#define XG_MAXVECTORS 64 - -void -ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs) -{ - FILE *file; - struct dvec *v, *scale; - double xval, yval; - int i, numVecs, linewidth; - bool xlog, ylog, nogrid, markers; - char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text; - - /* Sanity checking. */ - for (v = vecs, numVecs = 0; v; v = v->v_link2) - numVecs++; - - if (numVecs == 0) { - return; - } else if (numVecs > XG_MAXVECTORS) { - fprintf(cp_err, "Error: too many vectors for Xgraph.\n"); - return; - } - - if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) - linewidth = 1; - - if (linewidth < 1) - linewidth = 1; - - if (!cp_getvar("pointstyle", CP_STRING, pointstyle, sizeof(pointstyle))) { - markers = FALSE; - } else { - if (cieq(pointstyle, "markers")) - markers = TRUE; - else - markers = FALSE; - } - - /* Make sure the gridtype is supported. */ - switch (gridtype) { - case GRID_LIN: - nogrid = xlog = ylog = FALSE; - break; - case GRID_XLOG: - xlog = TRUE; - nogrid = ylog = FALSE; - break; - case GRID_YLOG: - ylog = TRUE; - nogrid = xlog = FALSE; - break; - case GRID_LOGLOG: - xlog = ylog = TRUE; - nogrid = FALSE; - break; - case GRID_NONE: - nogrid = TRUE; - xlog = ylog = FALSE; - break; - default: - fprintf(cp_err, "Error: grid type unsupported by Xgraph.\n"); - return; - } - - /* Open the output file. */ - if ((file = fopen(filename, "w")) == NULL) { - perror(filename); - return; - } - - /* Set up the file header. */ - if (title) { - text = cp_unquote(title); - fprintf(file, "TitleText: %s\n", text); - tfree(text); - } - if (xlabel) { - text = cp_unquote(xlabel); - fprintf(file, "XUnitText: %s\n", text); - tfree(text); - } - if (ylabel) { - text = cp_unquote(ylabel); - fprintf(file, "YUnitText: %s\n", text); - tfree(text); - } - if (nogrid) { - fprintf(file, "Ticks: True\n"); - } - - if (xlog) { - fprintf(file, "LogX: True\n"); - if (xlims) { - fprintf(file, "XLowLimit: % e\n", log10(xlims[0])); - fprintf(file, "XHighLimit: % e\n", log10(xlims[1])); - } - } else { - if (xlims) { - fprintf(file, "XLowLimit: % e\n", xlims[0]); - fprintf(file, "XHighLimit: % e\n", xlims[1]); - } - } - - if (ylog) { - fprintf(file, "LogY: True\n"); - if (ylims) { - fprintf(file, "YLowLimit: % e\n", log10(ylims[0])); - fprintf(file, "YHighLimit: % e\n", log10(ylims[1])); - } - } else { - if (ylims) { - fprintf(file, "YLowLimit: % e\n", ylims[0]); - fprintf(file, "YHighLimit: % e\n", ylims[1]); - } - } - - fprintf(file, "LineWidth: %d\n", linewidth); - fprintf(file, "BoundBox: True\n"); - - if (plottype == PLOT_COMB) { - fprintf(file, "BarGraph: True\n"); - fprintf(file, "NoLines: True\n"); - } else if (plottype == PLOT_POINT) { - if (markers) - fprintf(file, "Markers: True\n"); - else - fprintf(file, "LargePixels: True\n"); - fprintf(file, "NoLines: True\n"); - } - - /* Write out the data. */ - for (v = vecs; v; v = v->v_link2) { - scale = v->v_scale; - if (v->v_name) - fprintf(file, "\"%s\"\n", v->v_name); - - for (i = 0; i < scale->v_length; i++) { - xval = isreal(scale) ? - scale->v_realdata[i] : realpart(scale->v_compdata[i]); - yval = isreal(v) ? - v->v_realdata[i] : realpart(v->v_compdata[i]); - fprintf(file, "% e % e\n", xval, yval); - } - fprintf(file, "\n"); - } - - (void) fclose(file); - (void) sprintf(buf, "xgraph %s &", filename); - (void) system(buf); -} diff --git a/src/frontend/plotting/xgraph.h b/src/frontend/plotting/xgraph.h deleted file mode 100644 index e900bfa54..000000000 --- a/src/frontend/plotting/xgraph.h +++ /dev/null @@ -1,13 +0,0 @@ -/************* - * Header file for xgraph.c - * 1999 E. Rouat - ************/ - -#ifndef ngspice_XGRAPH_H -#define ngspice_XGRAPH_H - -void ft_xgraph(double *xlims, double *ylims, char *filename, char *title, - char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, - struct dvec *vecs); - -#endif diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj index 737d57b29..99a98c4da 100644 --- a/visualc/vngspice.vcxproj +++ b/visualc/vngspice.vcxproj @@ -1511,7 +1511,6 @@ - From 3e197c954e400e025fa1a43d661a5f55307135e5 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 16 Feb 2020 14:39:40 +0100 Subject: [PATCH 79/98] remove all the remains of quote() and strip() that had been used to modify the eigths bit of a character or string. The functions had been switched off some time ago. We now need all bits of a char for extended ascii or utf8 --- src/frontend/breakp2.c | 1 - src/frontend/com_alias.c | 1 - src/frontend/com_chdir.c | 1 - src/frontend/com_compose.c | 2 -- src/frontend/com_display.c | 1 - src/frontend/com_echo.c | 1 - src/frontend/com_setscale.c | 1 - src/frontend/com_strcmp.c | 1 - src/frontend/control.c | 3 -- src/frontend/cpitf.c | 3 -- src/frontend/inpcom.c | 6 ---- src/frontend/newcoms.c | 1 - src/frontend/parser/lexical.c | 17 +++++------ src/frontend/postcoms.c | 1 - src/frontend/quote.c | 55 ++-------------------------------- src/frontend/resource.c | 1 - src/frontend/streams.c | 1 - src/frontend/variable.c | 3 -- src/include/ngspice/cpextern.h | 5 ---- src/include/ngspice/wordlist.h | 15 ---------- src/main.c | 4 +-- src/misc/wlist.c | 2 +- visualc/vngspice.vcxproj | 1 - 23 files changed, 12 insertions(+), 115 deletions(-) diff --git a/src/frontend/breakp2.c b/src/frontend/breakp2.c index 14c2d7f4b..56cc9f463 100644 --- a/src/frontend/breakp2.c +++ b/src/frontend/breakp2.c @@ -12,7 +12,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/ftedefs.h" #include "ngspice/dvec.h" #include "ngspice/ftedebug.h" -#include "quote.h" #include "breakp2.h" diff --git a/src/frontend/com_alias.c b/src/frontend/com_alias.c index c1d06cc13..d417b703c 100644 --- a/src/frontend/com_alias.c +++ b/src/frontend/com_alias.c @@ -152,7 +152,6 @@ cp_setalias(char *word, wordlist *wlist) al->al_name = copy(word); al->al_text = wl_copy(wlist); - cp_striplist(al->al_text); /* We can afford to not worry about the bits, because before the * keyword lookup is done the alias is evaluated. Make everything * file completion, just in case... */ diff --git a/src/frontend/com_chdir.c b/src/frontend/com_chdir.c index 4beee8860..a8cf8d83e 100644 --- a/src/frontend/com_chdir.c +++ b/src/frontend/com_chdir.c @@ -11,7 +11,6 @@ #endif #include "com_chdir.h" -#include "quote.h" #include "ngspice/cpextern.h" diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c index 4c80a8170..099e68c8b 100644 --- a/src/frontend/com_compose.c +++ b/src/frontend/com_compose.c @@ -11,8 +11,6 @@ #include "ngspice/fteext.h" #include "ngspice/cpextern.h" #include "ngspice/randnumb.h" - -#include "quote.h" #include "com_compose.h" #include "completion.h" diff --git a/src/frontend/com_display.c b/src/frontend/com_display.c index 37fa68251..1fef086a7 100644 --- a/src/frontend/com_display.c +++ b/src/frontend/com_display.c @@ -5,7 +5,6 @@ #include "ngspice/cpextern.h" #include "com_display.h" -#include "quote.h" #include "variable.h" #include "plotting/plotting.h" #include "plotting/pvec.h" diff --git a/src/frontend/com_echo.c b/src/frontend/com_echo.c index 28c030f55..75d411130 100644 --- a/src/frontend/com_echo.c +++ b/src/frontend/com_echo.c @@ -7,7 +7,6 @@ #include "ngspice/bool.h" #include "com_echo.h" -#include "quote.h" #include "ngspice/cpextern.h" diff --git a/src/frontend/com_setscale.c b/src/frontend/com_setscale.c index fb0d00297..024bb043d 100644 --- a/src/frontend/com_setscale.c +++ b/src/frontend/com_setscale.c @@ -3,7 +3,6 @@ #include "ngspice/dvec.h" #include "com_setscale.h" -#include "quote.h" #include "ngspice/cpextern.h" #include "vectors.h" #include "plotting/plotting.h" diff --git a/src/frontend/com_strcmp.c b/src/frontend/com_strcmp.c index 5d259cda8..014a8025a 100644 --- a/src/frontend/com_strcmp.c +++ b/src/frontend/com_strcmp.c @@ -4,7 +4,6 @@ #include "ngspice/wordlist.h" #include "com_strcmp.h" -#include "quote.h" #include "variable.h" diff --git a/src/frontend/control.c b/src/frontend/control.c index e322df45f..157a43b75 100644 --- a/src/frontend/control.c +++ b/src/frontend/control.c @@ -192,9 +192,6 @@ docommand(wordlist *wlist) return; } - /* Get rid of all the 8th bits now... */ - cp_striplist(wlist); - s = wlist->wl_word; /* Look for the command in the command list. */ diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index 246012c66..f4d984097 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -262,7 +262,6 @@ ft_cpinit(void) { wordlist *wl; wl = cp_doglob(cp_lexer(buf)); - cp_striplist(wl); com_set(wl); wl_free(wl); } @@ -339,8 +338,6 @@ cp_istrue(wordlist *wl) return FALSE; /* backquote '`' substitution */ wl = cp_bquote(wl); - /* strip bit number eight */ - cp_striplist(wl); /* parse the condition */ names = ft_getpnames(wl, TRUE); diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 64d40ba44..d4f440f7d 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1364,7 +1364,6 @@ static char *inp_pathresolve(const char *name) switch (v->va_type) { case CP_STRING: - cp_wstrip(v->va_string); rc_ds = ds_cat_printf(&ds, "%s%s%s", v->va_string, DIR_PATHSEP, name); break; @@ -2431,11 +2430,6 @@ void inp_casefix(char *string) } if (string) while (*string) { -#ifdef HAS_ASCII - /* ((*string) & 0177): mask off all but the first seven bits, - * 0177: octal */ - *string = (char) strip(*string); -#endif if (*string == '"') { *string++ = ' '; while (*string && *string != '"') diff --git a/src/frontend/newcoms.c b/src/frontend/newcoms.c index 34ee8370d..21723a2b9 100644 --- a/src/frontend/newcoms.c +++ b/src/frontend/newcoms.c @@ -14,7 +14,6 @@ Copyright 1992 Regents of the University of California. All rights reserved. #include "ngspice/stringskip.h" #include "newcoms.h" -#include "quote.h" /* diff --git a/src/frontend/parser/lexical.c b/src/frontend/parser/lexical.c index cd970ea3a..ee961a1b2 100644 --- a/src/frontend/parser/lexical.c +++ b/src/frontend/parser/lexical.c @@ -200,13 +200,10 @@ nloop: if (c != EOF) numeofs = 0; - if (c != EOF) /* Don't need to do this really. */ - c = strip(c); - /* if '\' or '^', add following character to linebuf */ if ((c == '\\' && DIR_TERM != '\\') || (c == '\026') /* ^V */ ) { - c = quote(cp_readchar(&string, cp_inp_cur)); - push(&linebuf, strip(c)); + c = cp_readchar(&string, cp_inp_cur); + push(&linebuf, c); } /* if reading from fcn backeval() for backquote subst. */ @@ -265,7 +262,7 @@ nloop: { if ((c == '\n') || (c == EOF) || (c == ESCAPE)) goto gotchar; - push(&buf, quote(c)); + push(&buf, c); push(&linebuf, c); } push(&linebuf, '\''); @@ -285,7 +282,7 @@ nloop: if (c == '\\') { push(&linebuf, c); c = cp_readchar(&string, cp_inp_cur); - push(&buf, quote(c)); + push(&buf, c); push(&linebuf, c); } else { push(&buf, c); @@ -459,15 +456,15 @@ prompt(void) s = "-> "; while (*s) { - switch (strip(*s)) { + switch (*s) { case '!': fprintf(cp_out, "%d", cp_event); break; case '\\': if (s[1]) - (void) putc(strip(*++s), cp_out); + (void) putc((*++s), cp_out); default: - (void) putc(strip(*s), cp_out); + (void) putc((*s), cp_out); } s++; } diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index 0484fcd4a..0f628424c 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -19,7 +19,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "completion.h" #include "postcoms.h" -#include "quote.h" #include "variable.h" #include "parser/complete.h" /* va: throwaway */ #include "plotting/plotting.h" diff --git a/src/frontend/quote.c b/src/frontend/quote.c index 3403d1e96..ffa9ff58c 100644 --- a/src/frontend/quote.c +++ b/src/frontend/quote.c @@ -3,52 +3,14 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********/ -/* - * - * Various things for quoting words. If this is not ascii, quote and - * strip are no-ops, so '' and \ quoting won't work. To fix this, sell - * your IBM machine and buy a vax. - */ #include #include "ngspice/ngspice.h" #include "ngspice/cpdefs.h" -#include "quote.h" -/* Strip all the 8th bits from a string (destructively). */ - -void -cp_wstrip(char *str) -{ - char c, d; - - if (str) - while ((c = *str) != '\0') { /* assign and test */ - d = (char) strip(c); - if (c != d) - *str = d; - str++; - } -} - - -/* Quote all characters in a word. */ - -void -cp_quoteword(char *str) -{ - if (str) - while (*str) { - *str = (char) quote(*str); - str++; - } -} - - -/* Print a word (strip the word first). */ - +/* Print a word */ void cp_printword(char *string, FILE *fp) { @@ -56,23 +18,10 @@ cp_printword(char *string, FILE *fp) if (string) for (s = string; *s; s++) - (void) putc((strip(*s)), fp); + (void) putc((*s), fp); } -/* (Destructively) strip all the words in a wlist. */ - -void -cp_striplist(wordlist *wlist) -{ - wordlist *wl; - - for (wl = wlist; wl; wl = wl->wl_next) - cp_wstrip(wl->wl_word); -} - - - /* Create a copy of the input string removing the enclosing quotes, * if they are present */ char * diff --git a/src/frontend/resource.c b/src/frontend/resource.c index 608b7ee44..37d07b6c1 100644 --- a/src/frontend/resource.c +++ b/src/frontend/resource.c @@ -16,7 +16,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/ftedefs.h" #include "circuits.h" -#include "quote.h" #include "resource.h" #include "variable.h" #include "ngspice/cktdefs.h" diff --git a/src/frontend/streams.c b/src/frontend/streams.c index e49a91a9b..c728526a5 100644 --- a/src/frontend/streams.c +++ b/src/frontend/streams.c @@ -10,7 +10,6 @@ #include "variable.h" #include "terminal.h" -#include "quote.h" #include "ngspice/cpextern.h" #include "streams.h" diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 0f0818ef4..a1027f192 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -15,7 +15,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "circuits.h" #include "com_history.h" -#include "quote.h" #include "ngspice/cpextern.h" #include "variable.h" @@ -728,7 +727,6 @@ cp_getvar(char *name, enum cp_types type, void *retval, size_t rsize) break; case CP_STRING: { /* Gotta be careful to have room. */ char *s = cp_unquote(v->va_string); - cp_wstrip(s); if (strlen(s) > rsize) { fprintf(stderr, "Warning: string length for variable %s is limited to %zu chars\n", v->va_name, rsize); /* limit the string length */ @@ -902,7 +900,6 @@ wordlist *vareval(/* NOT const */ char *string) /* usage of vfree: variable v has to be freed only if created by cp_enqvar()! */ - cp_wstrip(string); if ((s = strchr(string, '[')) != NULL) { *s = '\0'; range = s + 1; diff --git a/src/include/ngspice/cpextern.h b/src/include/ngspice/cpextern.h index 8d18caf34..539ea9c9f 100644 --- a/src/include/ngspice/cpextern.h +++ b/src/include/ngspice/cpextern.h @@ -134,11 +134,6 @@ extern void out_send(char *string); /* quote.c */ extern char *cp_unquote(const char *string); -extern void cp_quoteword(char *str); -extern void cp_striplist(wordlist *wlist); -extern void cp_wstrip(char *str); - - /* unixcom.c */ diff --git a/src/include/ngspice/wordlist.h b/src/include/ngspice/wordlist.h index 713ef26a2..2978d0482 100644 --- a/src/include/ngspice/wordlist.h +++ b/src/include/ngspice/wordlist.h @@ -34,19 +34,4 @@ void wl_sort(wordlist *wl); wordlist * wl_splice(wordlist *elt, wordlist *list); - - - -#ifdef QUOTE_CHAR -/* For quoting individual characters. '' strings are all quoted, but - * `` and "" strings are maintained as single words with the quotes - * around them. Note that this won't work on non-ascii machines. */ -#define quote(c) ((c) | 0200) -#define strip(c) ((c) & 0177) -#else -#define quote(c) (c) -#define strip(c) (c) -#endif - - #endif diff --git a/src/main.c b/src/main.c index eaebb7843..9f133033d 100644 --- a/src/main.c +++ b/src/main.c @@ -544,14 +544,14 @@ prompt(void) s = "->"; while (*s) { - char c = (char) strip(*s++); + char c = (char) (*s++); switch (c) { case '!': p += sprintf(p, "%d", where_history() + 1); break; case '\\': if (*s) - c = (char) strip(*s++); + c = (char) (*s++); default: *p++ = c; break; diff --git a/src/misc/wlist.c b/src/misc/wlist.c index e94fa93b3..f6d9e2592 100644 --- a/src/misc/wlist.c +++ b/src/misc/wlist.c @@ -82,7 +82,7 @@ printword(const char *string, FILE *fp) { if (string) { while (*string) { - putc(strip(*string++), fp); + putc((*string++), fp); } } } diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj index 99a98c4da..1719a68d5 100644 --- a/visualc/vngspice.vcxproj +++ b/visualc/vngspice.vcxproj @@ -906,7 +906,6 @@ - From eee2b0b7fa55cd472fb26a99e92e576ab15c6a9d Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 16 Feb 2020 18:29:01 +0100 Subject: [PATCH 80/98] just another remains of quote --- src/frontend/parser/complete.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/frontend/parser/complete.c b/src/frontend/parser/complete.c index 794ae3b3a..7264167b9 100644 --- a/src/frontend/parser/complete.c +++ b/src/frontend/parser/complete.c @@ -91,7 +91,6 @@ cp_ccom(wordlist *wlist, char *buf, bool esc) int j, arg; buf = cp_unquote(copy(buf)); - cp_wstrip(buf); if (wlist) { /* Not the first word. */ cc = getccom(wlist->wl_word); if (cc && cc->cc_invalid) From 835c99560e19939c880871ed2a33be624e3e0fd4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 17 Feb 2020 21:53:41 +0100 Subject: [PATCH 81/98] single space indent in analysis window --- src/winmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index 9e7be66b7..cbacdd7d4 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -237,15 +237,15 @@ SetAnalyse(char *Analyse, /* in: analysis type */ sprintf(t, "%s", PACKAGE_STRING); } else if (DecaPercent == 0) { - sprintf(s, "%s", Analyse); + sprintf(s, " %s", Analyse); sprintf(t, "%s %s", PACKAGE_STRING, Analyse); } else if (!strcmp(Analyse, "shooting")) { - sprintf(s, "%s: %d", Analyse, DecaPercent); + sprintf(s, " %s: %d", Analyse, DecaPercent); sprintf(t, "%s %d", PACKAGE_STRING, DecaPercent); } else { - sprintf(s, "%s: %3.1f%%", Analyse, (double)DecaPercent/10.); + sprintf(s, " %s: %3.1f%%", Analyse, (double)DecaPercent/10.); sprintf(t, "%s %3.1f%%", PACKAGE_STRING, (double)DecaPercent/10.); } timebefore.dstflag = timenow.dstflag; From be02c10637bf2098a19885e89fcbfe88c3e700f4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 18 Feb 2020 22:39:38 +0100 Subject: [PATCH 82/98] add const declaration to newfopen --- src/include/ngspice/ngspice.h | 2 +- src/misc/util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index aafff44b6..8b3293176 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -221,7 +221,7 @@ extern double x_atanh(double); #ifndef EXT_ASC #if defined(__MINGW__) || defined(_MSC_VER) #define fopen newfopen -extern FILE *newfopen(char *fn, char* md); +extern FILE *newfopen(const char *fn, const char* md); #endif #endif diff --git a/src/misc/util.c b/src/misc/util.c index 0cd320cbb..132560903 100644 --- a/src/misc/util.c +++ b/src/misc/util.c @@ -264,7 +264,7 @@ ngdirname(const char *name) #undef BOOLEAN #include FILE * -newfopen(char *fn, char* md) +newfopen(const char *fn, const char* md) { if (fn == NULL) return NULL; From 44cca07fea3947f8b18d83a3170fd488ebb8023b Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 18 Feb 2020 22:59:36 +0100 Subject: [PATCH 83/98] plug a memory leak in inpcom.c vdmos code --- src/frontend/inpcom.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index d4f440f7d..fdc7393fe 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -6935,10 +6935,10 @@ static int inp_vdmos_model(struct card *deck) wl_append_word(&wl, &wl, copy_substring(curr_line, cut_line)); wlb = wl; if (strstr(cut_line, "pchan")) { - wl_append_word(NULL, &wl, "vdmosp ("); + wl_append_word(NULL, &wl, copy("vdmosp (")); } else { - wl_append_word(NULL, &wl, "vdmosn ("); + wl_append_word(NULL, &wl, copy("vdmosn (")); } cut_line = cut_line + 5; @@ -6949,17 +6949,20 @@ static int inp_vdmos_model(struct card *deck) while (cut_line && *cut_line) { token = gettok_model(&cut_line); if (!ciprefix("pchan", token) && !ciprefix("ron=", token) && - !ciprefix("vds=", token) && !ciprefix("qg=", token) && - !ciprefix("mfg=", token) && !ciprefix("nchan", token)) + !ciprefix("vds=", token) && !ciprefix("qg=", token) && + !ciprefix("mfg=", token) && !ciprefix("nchan", token)) wl_append_word(NULL, &wl, token); + else + tfree(token); if (*cut_line == ')') { - wl_append_word(NULL, &wl, ")"); + wl_append_word(NULL, &wl, copy(")")); break; } } new_line = wl_flatten(wlb); tfree(card->line); card->line = new_line; + wl_free(wlb); } /* we have a VDMOS instance line with 'tnodeout' and thus need exactly 5 nodes */ From 65a407221562783b7e55738b72c8198bd0592958 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 22 Feb 2020 10:14:25 +0100 Subject: [PATCH 84/98] Preliminary 'fix' to a plotting bug (visible return line in an array of curves): Partially undo code added in commit https://sourceforge.net/p/ngspice/ngspice/ci/10415875f46c46d91eb0b35e436cfa16aab0cd8f/ This will need further discussion or updates --- src/frontend/plotting/graf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 8e2ab37e6..4727511d8 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -420,7 +420,8 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) } currentgraph->plotdata = link; - +#if 0 + /* FIXME: this piece of code causes bug no. #472 */ /* Add the scale vector to the list of vectors associated with the plot * and use the copy instead of the original scale vector if requested */ { @@ -444,6 +445,7 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) currentgraph->plotdata = link; } } +#endif /* Put the legend entry on the screen. */ From 0845ce5329271fe0f6da83eaa40ee9b325b511f4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 22 Feb 2020 12:10:50 +0100 Subject: [PATCH 85/98] enable "null allowed" for reset input --- src/xspice/icm/digital/d_state/cfunc.mod | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xspice/icm/digital/d_state/cfunc.mod b/src/xspice/icm/digital/d_state/cfunc.mod index 18f4ed371..8fc56db45 100644 --- a/src/xspice/icm/digital/d_state/cfunc.mod +++ b/src/xspice/icm/digital/d_state/cfunc.mod @@ -1879,7 +1879,9 @@ void cm_d_state(ARGS) LOAD(clk) = PARAM(clk_load); - LOAD(reset) = PARAM(reset_load); + if ( !PORT_NULL(reset) ) { + LOAD(reset) = PARAM(reset_load); + } } else { /**** Retrieve previous values ****/ From 088a1e87c7fedae26034f3fd44411979c784f948 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 22 Feb 2020 15:49:36 +0100 Subject: [PATCH 86/98] required for reliable re-plotting, however still has the return line bug no #472 --- src/frontend/plotting/graf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 4727511d8..9eabc0654 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -420,7 +420,7 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) } currentgraph->plotdata = link; -#if 0 + /* FIXME: this piece of code causes bug no. #472 */ /* Add the scale vector to the list of vectors associated with the plot * and use the copy instead of the original scale vector if requested */ @@ -445,7 +445,6 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) currentgraph->plotdata = link; } } -#endif /* Put the legend entry on the screen. */ From b26c054f51b19f2bf0a23cc7caad589710646308 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 22 Feb 2020 15:50:19 +0100 Subject: [PATCH 87/98] replace variable 'gridwidth' by 'xgridwidth' --- examples/utf-8/стекло/ext-utf8-2.cir | 4 ++-- examples/utf-8/стекло/ext-utf8-3.cir | 4 ++-- examples/utf-8/стекло/ext-utf8-c.cir | 4 ++-- examples/utf-8/стекло/ext-utf8-c2.cir | 4 ++-- examples/utf-8/стекло/ext-utf8-c4.cir | 4 ++-- examples/utf-8/стекло/있어요/ext-utf8-3.cir | 4 ++-- src/frontend/plotting/gnuplot.c | 2 +- src/frontend/plotting/x11.c | 2 +- src/frontend/postsc.c | 2 +- src/frontend/wdisp/windisp.c | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir index e12d0cb08..194e77fe0 100644 --- a/examples/utf-8/стекло/ext-utf8-2.cir +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -15,7 +15,7 @@ set wfont_size=18 setcs xfont='Noto Sans Chinese' *set xfont_size=18 -set gridwidth=4 +set xgridwidth=4 set xbrushwidth=1 plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' @@ -23,7 +23,7 @@ plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу ес * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -set gridwidth=1 +set xgridwidth=1 set xbrushwidth=4 plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog diff --git a/examples/utf-8/стекло/ext-utf8-3.cir b/examples/utf-8/стекло/ext-utf8-3.cir index d1b46d0e9..4fe53fc3b 100644 --- a/examples/utf-8/стекло/ext-utf8-3.cir +++ b/examples/utf-8/стекло/ext-utf8-3.cir @@ -23,7 +23,7 @@ set wfont_size=18 setcs xfont='Noto Sans' *set xfont_size=18 -set gridwidth=4 +set xgridwidth=4 set xbrushwidth=1 *hardcopy @@ -36,7 +36,7 @@ if $oscompiled = 6 endif gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -set gridwidth=1 +set xgridwidth=1 set xbrushwidth=4 plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog diff --git a/examples/utf-8/стекло/ext-utf8-c.cir b/examples/utf-8/стекло/ext-utf8-c.cir index 149977a56..a4b336463 100644 --- a/examples/utf-8/стекло/ext-utf8-c.cir +++ b/examples/utf-8/стекло/ext-utf8-c.cir @@ -17,7 +17,7 @@ set wfont_size=18 setcs xfont='Noto Sans' *set xfont_size=18 -set gridwidth=4 +set xgridwidth=4 set xbrushwidth=1 set color0=white set color2=brown @@ -29,7 +29,7 @@ plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу ес set color0=Blue set color1=Yellow set color2=Lime -set gridwidth=1 +set xgridwidth=1 set xbrushwidth=4 plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog unset color1 diff --git a/examples/utf-8/стекло/ext-utf8-c2.cir b/examples/utf-8/стекло/ext-utf8-c2.cir index 08eea2af8..d1ae08e3b 100644 --- a/examples/utf-8/стекло/ext-utf8-c2.cir +++ b/examples/utf-8/стекло/ext-utf8-c2.cir @@ -17,7 +17,7 @@ set wfont_size=18 setcs xfont='Noto Sans' *set xfont_size=18 -set gridwidth=4 +set xgridwidth=4 set xbrushwidth=1 set color0=white *set color2=brown @@ -30,7 +30,7 @@ plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу ес set color0=Blue set color1=Yellow set color2=rgb:00/FF/00 -set gridwidth=1 +set xgridwidth=1 set xbrushwidth=4 plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog unset color1 diff --git a/examples/utf-8/стекло/ext-utf8-c4.cir b/examples/utf-8/стекло/ext-utf8-c4.cir index a2bdabaa6..8543156dd 100644 --- a/examples/utf-8/стекло/ext-utf8-c4.cir +++ b/examples/utf-8/стекло/ext-utf8-c4.cir @@ -11,7 +11,7 @@ setcs xfont='Noto Sans CJK JP' *setcs xfont='맑은 고딕' set xfont_size=20 -set gridwidth=1 +set xgridwidth=1 set xbrushwidth=8 set color2=rgbd:0/126/0 set color0=blue @@ -22,7 +22,7 @@ set color2=rgbd:0/0/255 set color1=rgb:0/0/0 set color0=white set xbrushwidth=4 -set gridwidth=2 +set xgridwidth=2 set nolegend plot y vs x xlabel '나는 유리를 먹을 수 있어요' ylabel 'それは私を傷つけません' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir index aa6305b8e..e3c17ad71 100644 --- a/examples/utf-8/стекло/있어요/ext-utf8-3.cir +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -15,7 +15,7 @@ set wfont_size=18 setcs xfont='Noto Sans CJK JP Medium' *set xfont_size=16 -set gridwidth=4 +set xgridwidth=4 set xbrushwidth=1 set nolegend @@ -27,7 +27,7 @@ plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу * With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" **gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' -set gridwidth=1 +set xgridwidth=1 set xbrushwidth=4 **plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index 9420a31aa..a99b1e56b 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -113,7 +113,7 @@ void ft_gnuplot(double *xlims, double *ylims, if (linewidth < 1) linewidth = 1; /* get linewidth for grid from .spiceinit */ - if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + if (!cp_getvar("xgridwidth", CP_NUM, &gridlinewidth, 0)) gridlinewidth = 1; if (gridlinewidth < 1) gridlinewidth = 1; diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index 370b3bdb6..8a88ce270 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -569,7 +569,7 @@ X11_NewViewport(GRAPH *graph) gcvalues.line_width = graph->graphwidth = linewidth; /* get linewidth information from .spiceinit or .control section */ - if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + if (!cp_getvar("xgridwidth", CP_NUM, &gridlinewidth, 0)) gridlinewidth = MW_LINEWIDTH; if (gridlinewidth < 0) gridlinewidth = MW_LINEWIDTH; diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index ec07a60eb..d7e0da70c 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -182,7 +182,7 @@ int PS_Init(void) linewidth = 0; /* get linewidth for grid from spinit */ - if (!cp_getvar("gridwidth", CP_REAL, &gridlinewidth, 0)) + if (!cp_getvar("xgridwidth", CP_REAL, &gridlinewidth, 0)) gridlinewidth = linewidth; if (gridlinewidth < 0) gridlinewidth = 0; diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 8ea6824d2..9ed9df0df 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -781,7 +781,7 @@ int WIN_NewViewport(GRAPH *graph) graph->graphwidth = linewidth; /* get linewidth information from .spiceinit or .control section */ - if (!cp_getvar("gridwidth", CP_NUM, &gridlinewidth, 0)) + if (!cp_getvar("xgridwidth", CP_NUM, &gridlinewidth, 0)) gridlinewidth = 0; if (gridlinewidth < 0) gridlinewidth = 0; From 07a203a7ce13a58712b978cdabd4049e34307d60 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 14:09:39 +0100 Subject: [PATCH 88/98] more precise warning of potential failure --- examples/utf-8/стекло/ext-ascii-1.cir | 2 ++ examples/utf-8/стекло/ext-ascii-2.cir | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/utf-8/стекло/ext-ascii-1.cir b/examples/utf-8/стекло/ext-ascii-1.cir index 5831febe1..146f874ce 100644 --- a/examples/utf-8/стекло/ext-ascii-1.cir +++ b/examples/utf-8/стекло/ext-ascii-1.cir @@ -1,5 +1,7 @@ * test de titre * file is encoded as ASCII ! +* will lead to error in the ngspice UNICODE utf8 version +* is o.k. only if ngspice is compiled with --disable-utf8 flag .control diff --git a/examples/utf-8/стекло/ext-ascii-2.cir b/examples/utf-8/стекло/ext-ascii-2.cir index 07a972dff..ddeee64b0 100644 --- a/examples/utf-8/стекло/ext-ascii-2.cir +++ b/examples/utf-8/стекло/ext-ascii-2.cir @@ -1,6 +1,7 @@ * test de titr * file is encoded as ASCII ! -* It will fail in utf8 mode. +* will lead to error in the ngspice UNICODE utf8 version +* is o.k. only if ngspice is compiled with --disable-utf8 flag .control set encoding=extended_ascii From 106207098ae8d06847466a8eb6b2e720871f7c7e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 14:10:31 +0100 Subject: [PATCH 89/98] thicken grid and graph separately --- examples/various/nmos_pmos_BSIM330.sp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/various/nmos_pmos_BSIM330.sp b/examples/various/nmos_pmos_BSIM330.sp index 20b266e7c..52c5d512e 100644 --- a/examples/various/nmos_pmos_BSIM330.sp +++ b/examples/various/nmos_pmos_BSIM330.sp @@ -26,6 +26,8 @@ vbsp 44 0 0 *.model p1 PMOS level=49 version=3.3.0 .control +set xgridwidth=2 +set xbrushwidth=3 dc vgs 0 1.5 0.05 vbs 0 -2.5 -0.5 plot vss#branch dc vds 0 2 0.05 vgs 0 2 0.4 From 5eb217fecde8aef89d00518bd1c445fcf3df37d7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 14:11:47 +0100 Subject: [PATCH 90/98] add a slight offset between y axis labels and grid --- src/frontend/plotting/grid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c index d8a57e5c8..468b42350 100644 --- a/src/frontend/plotting/grid.c +++ b/src/frontend/plotting/grid.c @@ -674,7 +674,7 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double ((int) strlen(buf) * graph->fontwidth) / 2, (int) (graph->fontheight * 2.5), 0); else - DevDrawText(buf, graph->viewportxoff - + DevDrawText(buf, graph->viewportxoff - 2 - graph->fontwidth * (int) strlen(buf), graph->viewportyoff + i - graph->fontheight / 2, 0); @@ -684,7 +684,7 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double j += 1000; } if (axis == x_axis) - DevDrawText(units, (int) (graph->absolute.width * RELPOSXUNIT + unitshift), graph->fontheight, 0); + DevDrawText(units, (int) (graph->absolute.width * RELPOSXUNIT + unitshift), graph->fontheight, 0); else DevDrawText(units, graph->fontwidth, (int) (graph->absolute.height - 2 * graph->fontheight), 0); From 00ebe289dd672b1df80b32306162f6741167522e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 14:18:29 +0100 Subject: [PATCH 91/98] Copy the scale vector as well and attach it to the data vector. Remove it again when the graph is destroyed. --- src/frontend/plotting/graf.c | 24 +++++------------------- src/frontend/plotting/graphdb.c | 2 ++ 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 9eabc0654..6c427daeb 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -319,7 +319,7 @@ void gr_point(struct dvec *dv, switch (currentgraph->plottype) { double *tics; case PLOT_LIN: - case PLOT_MONOLIN: + case PLOT_RETLIN: /* If it's a linear plot, ignore first point since we don't want to connect with oldx and oldy. */ if (np) @@ -421,32 +421,18 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) currentgraph->plotdata = link; - /* FIXME: this piece of code causes bug no. #472 */ - /* Add the scale vector to the list of vectors associated with the plot + /* Copy the scale vector, add it to the vector as v_scale * and use the copy instead of the original scale vector if requested */ { struct dvec * const custom_scale = dv->v_scale; - if (custom_scale != (struct dvec *) NULL) { - link = TMALLOC(struct dveclist, 1); - link->next = currentgraph->plotdata; - + if (custom_scale != (struct dvec*) NULL) { if (copyvec) { - link->vector = vec_copy(dv->v_scale); - link->vector->v_flags |= VF_PERMANENT; - link->next->vector->v_scale = link->vector; - link->f_own_vector = TRUE; + currentgraph->plotdata->vector->v_scale = vec_copy(dv->v_scale); + currentgraph->plotdata->vector->v_scale->v_flags |= VF_PERMANENT; } - else { - link->vector = dv->v_scale; - link->f_own_vector = FALSE; - } - - /* Make the new vector the start of the list of vectors */ - currentgraph->plotdata = link; } } - /* Put the legend entry on the screen. */ if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) drawlegend(currentgraph, cur.plotno++, dv); diff --git a/src/frontend/plotting/graphdb.c b/src/frontend/plotting/graphdb.c index 4ca5cf432..82656ea44 100644 --- a/src/frontend/plotting/graphdb.c +++ b/src/frontend/plotting/graphdb.c @@ -259,6 +259,8 @@ int DestroyGraph(int id) nextd = d->next; if (d->f_own_vector) { /* list responsible for freeing this vector */ + if (d->vector->v_scale) + dvec_free(d->vector->v_scale); dvec_free(d->vector); } txfree(d); From b7b77a956133c9d26b93f0909de49f4225213bec Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 14:27:14 +0100 Subject: [PATCH 92/98] When plotting arrays of curves, plot lines only in the direction of (in absolute terms) growing x values. Example: MOS output characteristics. In the rare case of plotting versus varying x directions (e.g. example memristor.sp), one has to add the flag 'retraceplot' to the plot command. --- examples/memristor/memristor.sp | 4 ++-- examples/memristor/memristor_x.sp | 8 ++++---- src/frontend/plotting/gnuplot.c | 2 +- src/frontend/plotting/plotcurv.c | 2 +- src/frontend/plotting/plotit.c | 10 +++++----- src/include/ngspice/dvec.h | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/memristor/memristor.sp b/examples/memristor/memristor.sp index fdb9488a7..0664f1075 100644 --- a/examples/memristor/memristor.sp +++ b/examples/memristor/memristor.sp @@ -57,9 +57,9 @@ plot tran1.alli tran2.alli alli title 'Memristor with threshold: Internal Progra settype impedance xmem.x1 tran1.xmem.x1 tran2.xmem.x1 plot xmem.x1 tran1.xmem.x1 tran2.xmem.x1 title 'Memristor with threshold: resistance' * resistance versus voltage (change occurs only above threshold!) -plot xmem.x1 vs v(1) tran1.xmem.x1 vs tran1.v(1) tran2.xmem.x1 vs tran2.v(1) title 'Memristor with threshold: resistance' +plot xmem.x1 vs v(1) tran1.xmem.x1 vs tran1.v(1) tran2.xmem.x1 vs tran2.v(1) retraceplot title 'Memristor with threshold: resistance' * current through resistor for all plots versus voltage -plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) title 'Memristor with threshold: external current loops' +plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) retraceplot title 'Memristor with threshold: external current loops' .endc .end diff --git a/examples/memristor/memristor_x.sp b/examples/memristor/memristor_x.sp index 1c283e734..98fbc6528 100644 --- a/examples/memristor/memristor_x.sp +++ b/examples/memristor/memristor_x.sp @@ -47,11 +47,11 @@ Rmem plus minus r={V(x)} op print all ac lin 101 1 100k -plot v(11) +*plot v(11) * approx. 100 simulation points let deltime = stime/100 tran $&deltime $&stime uic -* plot i(v1) vs v(1) +*plot i(v1) vs v(1) retrace *** you may just stop here *** * raise the frequency let newfreq = 1.2/stime @@ -75,9 +75,9 @@ let res2 = tran2.v(1)/(tran2.I(v1) + 1e-16) settype impedance res res1 res2 plot res vs time res1 vs tran1.time res2 vs tran2.time title 'Memristor with threshold: resistance' * resistance versus voltage (change occurs only above threshold!) -plot res vs v(1) res1 vs tran1.v(1) res2 vs tran2.v(1) title 'Memristor with threshold: resistance' +plot res vs v(1) res1 vs tran1.v(1) res2 vs tran2.v(1) retraceplot title 'Memristor with threshold: resistance' * current through resistor for all plots versus voltage -plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) title 'Memristor with threshold: external current loops' +plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) retraceplot title 'Memristor with threshold: external current loops' .endc .end diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index a99b1e56b..96a77fd5d 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -319,7 +319,7 @@ void ft_gnuplot(double *xlims, double *ylims, (void) fclose(file); /* Write out the data and setup arrays */ - bool mono = (plottype == PLOT_MONOLIN); + bool mono = (plottype != PLOT_RETLIN); dir = 0; prev_xval = NAN; for (i = 0; i < scale->v_length; i++) { diff --git a/src/frontend/plotting/plotcurv.c b/src/frontend/plotting/plotcurv.c index 768e9560d..da7026adb 100644 --- a/src/frontend/plotting/plotcurv.c +++ b/src/frontend/plotting/plotcurv.c @@ -130,7 +130,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart) * interpolation. */ if ((degree == 1) && (gridsize == 0)) { - bool mono = (currentgraph->plottype == PLOT_MONOLIN); + bool mono = (currentgraph->plottype != PLOT_RETLIN); dir = 0; for (i = 0, j = v->v_length; i < j; i++) { dx = isreal(xs) ? xs->v_realdata[i] : diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index 997ada184..6e91694fd 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -600,14 +600,14 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) pfound = TRUE; } } - if (getflag(wl, "noretraceplot")) { + if (getflag(wl, "retraceplot")) { if (pfound) { fprintf(cp_err, "Warning: too many plot types given. " - "\"noretraceplot\" is ignored.\n"); + "\"retraceplot\" is ignored.\n"); } else { - ptype = PLOT_MONOLIN; + ptype = PLOT_RETLIN; pfound = TRUE; } } @@ -640,8 +640,8 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) if (eq(buf, "linplot")) { ptype = PLOT_LIN; } - else if (eq(buf, "noretraceplot")) { - ptype = PLOT_MONOLIN; + else if (eq(buf, "retraceplot")) { + ptype = PLOT_RETLIN; } else if (eq(buf, "combplot")) { ptype = PLOT_COMB; diff --git a/src/include/ngspice/dvec.h b/src/include/ngspice/dvec.h index 3833295b7..ea0a9b83c 100644 --- a/src/include/ngspice/dvec.h +++ b/src/include/ngspice/dvec.h @@ -22,7 +22,7 @@ enum dvec_flags { /* Plot types. */ typedef enum { - PLOT_LIN, PLOT_COMB, PLOT_POINT, PLOT_MONOLIN + PLOT_LIN, PLOT_COMB, PLOT_POINT, PLOT_RETLIN } PLOTTYPE; From 99cfe7bc81fa6fce7390e290d690d231d64fdf51 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 14:28:29 +0100 Subject: [PATCH 93/98] MOS output characteristics with and witout drain series resistance --- examples/various/nmos_out_BSIM330.sp | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 examples/various/nmos_out_BSIM330.sp diff --git a/examples/various/nmos_out_BSIM330.sp b/examples/various/nmos_out_BSIM330.sp new file mode 100644 index 000000000..20338b5a3 --- /dev/null +++ b/examples/various/nmos_out_BSIM330.sp @@ -0,0 +1,37 @@ +***** NMOS Transistor BSIM3 (Id-Vds) with Rd *** + +M1 2 1 3 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p +vgs 1 0 3.5 +vds 2 0 0.1 +vss 3 0 0 +vbs 4 0 0 + +* drain series resistor +R2 2 22 1k +M2 22 1 32 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p +vss2 32 0 0 + + +.options Temp=27.0 + +* BSIM3v3.3.0 model with modified default parameters 0.18m +.model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 +.model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 + +.control +set xgridwidth=2 +set xbrushwidth=3 +dc vds 0 2 0.05 vgs 0 2 0.4 +set nolegend +plot vss#branch title 'Drain current versus drain voltage' xlabel 'Drain voltage' ylabel 'Drain current' +unset nolegend +set color0=white +plot vss2#branch vs v(22) title 'Series resistor: Drain current versus drain voltage' xlabel 'Drain voltage' ylabel 'Drain current' +.endc + +.end + + + + + From 9f8509d53cd96aa66ca94a59a2f8ff30fe611cdb Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 15:38:49 +0100 Subject: [PATCH 94/98] prevent double closing of file (Linux does not NULL fp during fclose) --- src/xspice/icm/table/table3D/cfunc.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xspice/icm/table/table3D/cfunc.mod b/src/xspice/icm/table/table3D/cfunc.mod index d354cc9c3..cb4c06e26 100644 --- a/src/xspice/icm/table/table3D/cfunc.mod +++ b/src/xspice/icm/table/table3D/cfunc.mod @@ -468,6 +468,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder) lFileRead = fread(cFile, sizeof(char), lFileLen, fp); const int file_error = ferror(fp); fclose(fp); /* done with file */ + fp = (FILE *) NULL; if (file_error) { cm_message_printf("Error reading data file %s", filename); xrc = -1; From 646ac2dbcbe304dd9a39c157b0aba791d73f6c37 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 23 Feb 2020 19:30:23 +0100 Subject: [PATCH 95/98] use errMsg under ngdebug condition and prevent memory leak --- src/spicelib/devices/cktask.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/spicelib/devices/cktask.c b/src/spicelib/devices/cktask.c index 203ac836c..884d6570f 100644 --- a/src/spicelib/devices/cktask.c +++ b/src/spicelib/devices/cktask.c @@ -29,7 +29,12 @@ CKTask(CKTcircuit *ckt, GENinstance *instance, int which, IFvalue *value, IFvalu } if (error && ft_stricterror) { fprintf(stderr, "\nError: %s\n", errMsg); + FREE(errMsg); controlled_exit(EXIT_BAD); } + if (error && ft_ngdebug) { + printf("\nWarning: %s\n", errMsg); + } + FREE(errMsg); return(error); } From 565a0994b3c863dbaaf0dffd9bd65f968211e4b1 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 23 Feb 2020 20:39:44 +0100 Subject: [PATCH 96/98] free errMsg only if available --- src/spicelib/devices/cktask.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spicelib/devices/cktask.c b/src/spicelib/devices/cktask.c index 884d6570f..9c9f9a453 100644 --- a/src/spicelib/devices/cktask.c +++ b/src/spicelib/devices/cktask.c @@ -35,6 +35,7 @@ CKTask(CKTcircuit *ckt, GENinstance *instance, int which, IFvalue *value, IFvalu if (error && ft_ngdebug) { printf("\nWarning: %s\n", errMsg); } - FREE(errMsg); + if (errMsg) + FREE(errMsg); return(error); } From e24dcf7d67762345d93b493171dfc104786bb10e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 23 Feb 2020 19:28:32 +0100 Subject: [PATCH 97/98] added features of utf-8 descrption --- README.utf8 | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.utf8 b/README.utf8 index a9e398f58..92472e34e 100644 --- a/README.utf8 +++ b/README.utf8 @@ -1,6 +1,6 @@ use utf-8 for encoding of strings, this enables UNICODE international characters sets (of nearly any language) -in titles, labels, file and folder names. +in plot titles and labels, file and folder names. Windows uses utf-16 and conversion functions between utf-8 and utf-16, if access to Windows API functions is needed. @@ -14,12 +14,22 @@ ISO-8859-1/ISO-8859-15, that allows extended ascii. Better looking fonts are now used for labelling the axes. -Variables xbrushwidth and gridwidth (to be set e.g. in -.spiceinit) allow setting separately the linewidths of the -graph (xbrushwidth) and the grid (gridwidth). +Variables xbrushwidth and xgridwidth (to be set e.g. in +.spiceinit or directly before a plot command) allow setting +separately the linewidths of the graph (xbrushwidth) and +the grid (xgridwidth). Slight modification of the Windows GUI string window to enhance readability. Windows GUI is now more responsive during lengthy op calculations. + +UNICODE in Gnuplot and (limited) in Postscript are supported. +You will need to download and install gnuplot and a PS viewer +(e.g. ghostscript, gv or others). + +Input files to ngspice now have to be utf-8 encoded. ANSI +encoded files will fail (Notepad++ on Windows allows a simple +conversion). For an ANSI version of ngspice you have to +compile it with the configure flag --disable-utf8. From 89b691e70f3297b1a074c7d309851bfe3a3a1f5b Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 23 Feb 2020 21:58:13 +0100 Subject: [PATCH 98/98] no xgraph anymore --- visualc/vngspice-fftw.vcxproj | 1 - 1 file changed, 1 deletion(-) diff --git a/visualc/vngspice-fftw.vcxproj b/visualc/vngspice-fftw.vcxproj index b60c10eef..e197090a0 100644 --- a/visualc/vngspice-fftw.vcxproj +++ b/visualc/vngspice-fftw.vcxproj @@ -1501,7 +1501,6 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3 -