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.
This commit is contained in:
Vogt 2020-02-10 17:21:46 +01:00 committed by Holger Vogt
parent 34b50c32de
commit 728ddae41e
15 changed files with 150 additions and 48 deletions

View File

@ -275,9 +275,9 @@ SetLinestyle(int linestyleid)
void
SetColor(int colorid)
SetColor(int colorid, GRAPH *graph)
{
dispdev->SetColor (colorid);
dispdev->SetColor (colorid, graph);
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -13,6 +13,7 @@
#undef BOOLEAN
#include <windows.h>
#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;

View File

@ -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)

View File

@ -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);

View File

@ -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.
*/