Windows port of Ngspice (Holger Vogt) (part 2)
This commit is contained in:
parent
937e3db647
commit
a7e1405208
|
|
@ -0,0 +1,11 @@
|
|||
noinst_LIBRARIES = libwindisp.a
|
||||
|
||||
libwindisp_a_SOURCES = \
|
||||
windisp.c \
|
||||
winprint.c \
|
||||
ftegraf.h
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend/wdisp
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
**********/
|
||||
|
||||
/*
|
||||
*
|
||||
* Definitions common to the various graphics modules.
|
||||
*/
|
||||
|
||||
#define G_NONE 0
|
||||
#define G_HCOPY 1
|
||||
#define G_TERM 2
|
||||
#define G_MFB 3
|
||||
#define G_X 4
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
###########
|
||||
# Copyright 2000 Holger Vogt. All rights reserved.
|
||||
###########
|
||||
|
||||
CFILES = windisp.c winprint.c
|
||||
|
||||
COBJS = windisp.o winprint.o
|
||||
|
||||
LIBRARY = wdisp
|
||||
LIB_TARGET = $(OBJLIB_DIR)/$(LIBRARY).a
|
||||
windisp.o: windisp.c
|
||||
winprint.o: winprint.c
|
||||
|
|
@ -0,0 +1,542 @@
|
|||
/*
|
||||
* Frame buffer for the IDM PC using MS Windows
|
||||
* Wolfgang Mües 27.10.97
|
||||
* Holger Vogt 07.12.01
|
||||
*/
|
||||
|
||||
#define STRICT
|
||||
#include "ngspice.h"
|
||||
|
||||
#ifdef HAS_WINDOWS
|
||||
|
||||
#include "graph.h"
|
||||
#include "ftedev.h"
|
||||
#include "ftedbgra.h"
|
||||
#pragma warn -dup // wegen Redefinition von NUMCOLORS
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include "suffix.h"
|
||||
#pragma hdrstop
|
||||
|
||||
// Typen
|
||||
typedef struct { // Extra Fensterdaten
|
||||
HWND wnd; // Fenster
|
||||
HDC hDC; // Device context des Fensters
|
||||
RECT Area; // Zeichenfläche
|
||||
int ColorIndex; // Index auf die akt. Farbe
|
||||
int PaintFlag; // 1 bei WM_PAINT
|
||||
int FirstFlag; // 1 vor dem ersten Update
|
||||
} tWindowData;
|
||||
typedef tWindowData * tpWindowData; // Zeiger darauf
|
||||
#define pWindowData(g) ((tpWindowData)(g->devdep))
|
||||
|
||||
// Forwards
|
||||
LRESULT CALLBACK PlotWindowProc( HWND hwnd, // Fensterprozedur
|
||||
UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// externals
|
||||
extern HINSTANCE hInst; // Instanz der Applikation
|
||||
extern int WinLineWidth; // Breite des Textfensters
|
||||
void WPRINT_PrintInit( HWND hwnd); // Windows Drucker Init
|
||||
void WaitForIdle(void); // Warte, bis keine Events da
|
||||
|
||||
// lokale Variablen
|
||||
static int IsRegistered = 0; // 1 wenn Fensterkl. reg.
|
||||
#define NumWinColors 23 // vordef. Farben
|
||||
static COLORREF ColorTable[NumWinColors]; // Speicher für die Farben
|
||||
static char * WindowName = "Spice Plot"; // Fenstername
|
||||
static WNDCLASS TheWndClass; // Plot-Fensterklasse
|
||||
static HFONT PlotFont; // Font-Merker
|
||||
#define ID_DRUCKEN 0xEFF0 // System-Menu: drucken
|
||||
#define ID_DRUCKEINR 0xEFE0 // System-Menu: Druckereinrichtung
|
||||
static const int ID_MASK = 0xFFF0; // System-Menu: Maske
|
||||
static char * STR_DRUCKEN = "Drucken..."; // System-Menu-Strings
|
||||
static char * STR_DRUCKEINR = "Druckereinrichtung...";
|
||||
|
||||
/******************************************************************************
|
||||
WIN_Init() stellt die Verbindung zur Grafik her. Dazu gehört die Feststellung
|
||||
von
|
||||
dispdev->numlinestyles (bei Farbschirmen == 1)
|
||||
dispdev->numcolors
|
||||
dispdev->width (vorläufig, Bildschirmbreite)
|
||||
dispdev->height (vorläufig, Bildschirmhöhe)
|
||||
|
||||
WIN_Init() gibt 0 zurück, falls kein Fehler auftrat.
|
||||
|
||||
WIN_Init() macht noch kein Fenster auf, dies geschieht erst in WIN_NewViewport()
|
||||
******************************************************************************/
|
||||
|
||||
int WIN_Init( )
|
||||
{
|
||||
// Initialisierungen des Display-Descriptors
|
||||
dispdev->width = GetSystemMetrics( SM_CXSCREEN);
|
||||
dispdev->height = GetSystemMetrics( SM_CYSCREEN);
|
||||
dispdev->numlinestyles = 5; // siehe Auswirkungen in WinPrint!
|
||||
dispdev->numcolors = NumWinColors;
|
||||
|
||||
// nur beim ersten Mal:
|
||||
if (!IsRegistered) {
|
||||
|
||||
// Farben initialisieren
|
||||
ColorTable[0] = RGB( 0, 0, 0); // Schwarz = Hintergrund
|
||||
ColorTable[1] = RGB(255,255,255); // Weiß = Beschriftung und Gitter
|
||||
ColorTable[2] = RGB( 0,255, 0); // Grün = erste Linie
|
||||
ColorTable[3] = RGB(255, 0, 0); // Rot
|
||||
ColorTable[4] = RGB( 0, 0,255); // Blau
|
||||
ColorTable[5] = RGB(255,255, 0); // Gelb
|
||||
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); // braun
|
||||
ColorTable[10]= RGB(128, 0,255); // Hellviolett
|
||||
ColorTable[11]= RGB(255,128,128); // Rosa
|
||||
// 2. Farb-Bank (mit anderem Linientyp
|
||||
ColorTable[12]= RGB(255,255,255); // Weiß
|
||||
ColorTable[13]= RGB( 0,255, 0); // Grün
|
||||
ColorTable[14]= RGB(255, 0, 0); // Rot
|
||||
ColorTable[15]= RGB( 0, 0,255); // Blau
|
||||
ColorTable[16]= RGB(255,255, 0); // Gelb
|
||||
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); // braun
|
||||
ColorTable[21]= RGB(128, 0,255); // Hellviolett
|
||||
ColorTable[22]= RGB(255,128,128); // Rosa
|
||||
|
||||
// Ansii fixed font
|
||||
PlotFont = GetStockFont( ANSI_FIXED_FONT);
|
||||
|
||||
// Fensterklasse registrieren
|
||||
TheWndClass.lpszClassName = WindowName;
|
||||
TheWndClass.hInstance = hInst;
|
||||
TheWndClass.lpfnWndProc = PlotWindowProc;
|
||||
TheWndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
||||
TheWndClass.lpszMenuName = NULL;
|
||||
TheWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
TheWndClass.hbrBackground = GetStockObject( BLACK_BRUSH);
|
||||
TheWndClass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(2));
|
||||
TheWndClass.cbClsExtra = 0;
|
||||
TheWndClass.cbWndExtra = sizeof(GRAPH *);
|
||||
if (!RegisterClass(&TheWndClass)) return 1;
|
||||
}
|
||||
IsRegistered = 1;
|
||||
|
||||
// fertig
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Zeiger auf den Graphen gewinnen
|
||||
// (wird an das Fenster angehängt)
|
||||
static GRAPH * pGraph( HWND hwnd)
|
||||
{
|
||||
return (GRAPH *) GetWindowLong( hwnd, 0);
|
||||
}
|
||||
|
||||
// Linientyp zurückgeben zum Zeichnen
|
||||
static int LType( int ColorIndex)
|
||||
{
|
||||
if (ColorIndex >= 12)
|
||||
return PS_DOT;
|
||||
else
|
||||
return PS_SOLID;
|
||||
}
|
||||
|
||||
// Drucke ein Plotfenster
|
||||
// Aufruf durch SystemMenü / Drucken
|
||||
LRESULT PrintPlot( HWND hwnd)
|
||||
{
|
||||
GRAPH * graph;
|
||||
GRAPH * temp;
|
||||
|
||||
// Zeiger auf die Grafik holen
|
||||
graph = pGraph( hwnd);
|
||||
if (!graph) return 0;
|
||||
|
||||
// Umschalten auf den Drucker
|
||||
// (hat WPRINT_Init() zur Folge)
|
||||
if (DevSwitch("WinPrint")) return 0;
|
||||
|
||||
// Cursor = warten
|
||||
SetCursor( LoadCursor( NULL, IDC_WAIT));
|
||||
|
||||
// Graphen kopieren
|
||||
temp = CopyGraph(graph);
|
||||
if (!temp) goto PrintEND;
|
||||
|
||||
// in die Kopie die neuen Daten des Druckers einspeisen
|
||||
if (NewViewport(temp)) goto PrintEND2;
|
||||
|
||||
// Lage des Gitters korrigieren (Kopie aus gr_init)
|
||||
temp->viewportxoff = temp->fontwidth * 8;
|
||||
temp->viewportyoff = temp->fontheight * 4;
|
||||
|
||||
// dies druckt den Graphen
|
||||
gr_resize(temp);
|
||||
|
||||
PrintEND2:
|
||||
// temp. Graphen löschen
|
||||
DestroyGraph(temp->graphid);
|
||||
|
||||
PrintEND:
|
||||
// zurückschalten auf den Bildschirm
|
||||
DevSwitch(NULL);
|
||||
|
||||
// Cursor = normal
|
||||
SetCursor( LoadCursor( NULL, IDC_ARROW));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Druckerinitialisierung
|
||||
LRESULT PrintInit( HWND hwnd)
|
||||
{
|
||||
// weitergeben an das Drucker-Modul
|
||||
WPRINT_PrintInit(hwnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fensterprozedur
|
||||
LRESULT CALLBACK PlotWindowProc( HWND hwnd,
|
||||
UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg) {
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
// Kommando testen
|
||||
int cmd = wParam & ID_MASK;
|
||||
switch(cmd) {
|
||||
case ID_DRUCKEN: return PrintPlot( hwnd);
|
||||
case ID_DRUCKEINR: return PrintInit( hwnd);
|
||||
}
|
||||
}
|
||||
goto WIN_DEFAULT;
|
||||
|
||||
case WM_CLOSE: // Fenster schließen
|
||||
{
|
||||
GRAPH * g = pGraph( hwnd);
|
||||
if (g)
|
||||
DestroyGraph(g->graphid);
|
||||
}
|
||||
goto WIN_DEFAULT;
|
||||
|
||||
case WM_PAINT: // Fenster neuzeichnen (z.B. nach Resize)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
GRAPH * g;
|
||||
tpWindowData wd;
|
||||
HDC saveDC; // der DC aus BeginPaint ist anders...
|
||||
HDC newDC;
|
||||
|
||||
// muss passieren
|
||||
newDC = BeginPaint( hwnd, &ps);
|
||||
g = pGraph( hwnd);
|
||||
if (g) {
|
||||
wd = pWindowData(g);
|
||||
if (wd) {
|
||||
if (!wd->PaintFlag && !wd->FirstFlag) {
|
||||
// rekursiven Aufruf verhindern
|
||||
wd->PaintFlag = 1;
|
||||
// Fenstermaße holen
|
||||
GetClientRect( hwnd, &(wd->Area));
|
||||
g->absolute.width = wd->Area.right;
|
||||
g->absolute.height = wd->Area.bottom;
|
||||
// DC umschalten
|
||||
saveDC = wd->hDC;
|
||||
wd->hDC = newDC;
|
||||
// neu zeichnen
|
||||
gr_resize(g);
|
||||
// DC umschalten
|
||||
wd->hDC = saveDC;
|
||||
// fertig
|
||||
wd->PaintFlag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// beenden
|
||||
EndPaint( hwnd, &ps);
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
WIN_DEFAULT:
|
||||
return DefWindowProc( hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
WIN_NewViewport() erstellt ein neues Fenster mit einem Graphen drin.
|
||||
|
||||
WIN_NewViewport() gibt 0 zurück, falls erfolgreich
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
int WIN_NewViewport( GRAPH * graph)
|
||||
{
|
||||
int i;
|
||||
HWND window;
|
||||
HDC dc;
|
||||
HDC textDC;
|
||||
HFONT font;
|
||||
TEXTMETRIC tm;
|
||||
tpWindowData wd;
|
||||
HMENU sysmenu;
|
||||
|
||||
// Parameter testen
|
||||
if (!graph) return 1;
|
||||
|
||||
// Initialisiere, falls noch nicht geschehen
|
||||
if (WIN_Init() != 0) {
|
||||
externalerror("Can't initialize GDI.");
|
||||
return(1);
|
||||
}
|
||||
|
||||
// Device dep. Info allocieren
|
||||
wd = calloc(1, sizeof(tWindowData));
|
||||
if (!wd) return 1;
|
||||
graph->devdep = (char *)wd;
|
||||
|
||||
// Create the window
|
||||
i = GetSystemMetrics( SM_CYSCREEN) / 3;
|
||||
window = CreateWindow( WindowName, graph->plotname, WS_OVERLAPPEDWINDOW,
|
||||
0, 0, WinLineWidth, i * 2 - 22, NULL, NULL, hInst, NULL);
|
||||
if (!window) return 1;
|
||||
wd->wnd = window;
|
||||
SetWindowLong( window, 0, (long)graph);
|
||||
|
||||
// Zeige das Fenster
|
||||
ShowWindow( window, SW_SHOWNORMAL);
|
||||
|
||||
// Hole die Maße
|
||||
GetClientRect( window, &(wd->Area));
|
||||
|
||||
// Hole den DC
|
||||
dc = GetDC( window);
|
||||
wd->hDC = dc;
|
||||
|
||||
// Setze den Color-Index
|
||||
wd->ColorIndex = 0;
|
||||
|
||||
// noch kein Zeichnen
|
||||
wd->PaintFlag = 0;
|
||||
wd->FirstFlag = 1;
|
||||
|
||||
// System-Menu modifizieren
|
||||
sysmenu = GetSystemMenu( window, FALSE);
|
||||
AppendMenu( sysmenu, MF_SEPARATOR, 0, NULL);
|
||||
AppendMenu( sysmenu, MF_STRING, ID_DRUCKEN, STR_DRUCKEN);
|
||||
AppendMenu( sysmenu, MF_STRING, ID_DRUCKEINR, STR_DRUCKEINR);
|
||||
|
||||
// Default-Parameter des DC setzen
|
||||
SetBkColor( dc, ColorTable[0]);
|
||||
SetBkMode( dc, TRANSPARENT );
|
||||
|
||||
// Font setzen
|
||||
SelectObject( dc, PlotFont);
|
||||
|
||||
// Font-Parameter abfragen
|
||||
if (GetTextMetrics( dc, &tm)) {
|
||||
graph->fontheight = tm.tmHeight;
|
||||
graph->fontwidth = tm.tmAveCharWidth;
|
||||
}
|
||||
|
||||
// Viewport-Parameter setzen
|
||||
graph->viewport.height = wd->Area.bottom;
|
||||
graph->viewport.width = wd->Area.right;
|
||||
|
||||
// Absolut-Parameter setzen
|
||||
graph->absolute.xpos = 0;
|
||||
graph->absolute.ypos = 0;
|
||||
graph->absolute.width = wd->Area.right;
|
||||
graph->absolute.height = wd->Area.bottom;
|
||||
|
||||
// Warten, bis das Fenster wirklich da ist
|
||||
WaitForIdle();
|
||||
|
||||
// fertig
|
||||
return(0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
WIN_Close ist eigentlich das Gegenstück zu WIN_Init. Dummerweise kann es
|
||||
passieren, daß (während gerade ein Plot dargestellt wird) WIN_Close aufgerufen
|
||||
wird, um auf einen Drucker umzuschalten. Deswegen darf WIN_Close nichts machen,
|
||||
sondern das Auflösen der Strukturen erfolgt bei Programmende.
|
||||
******************************************************************************/
|
||||
|
||||
int WIN_Close()
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void RealClose(void)
|
||||
{
|
||||
// Fensterklasse löschen
|
||||
if (IsRegistered) {
|
||||
if (TheWndClass.hIcon) {
|
||||
DestroyIcon( TheWndClass.hIcon);
|
||||
TheWndClass.hIcon = NULL;
|
||||
}
|
||||
UnregisterClass( WindowName, hInst);
|
||||
IsRegistered = FALSE;
|
||||
}
|
||||
}
|
||||
#pragma exit RealClose
|
||||
|
||||
int WIN_Clear()
|
||||
{
|
||||
tpWindowData wd;
|
||||
if (!currentgraph) return 0;
|
||||
wd = pWindowData(currentgraph);
|
||||
if (!wd) return 0;
|
||||
|
||||
// das macht das Fenster selbst
|
||||
if (!wd->PaintFlag) // bei WM_PAINT unnötig
|
||||
SendMessage( wd->wnd, WM_ERASEBKGND, (WPARAM) wd->hDC, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int WIN_DrawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
tpWindowData wd;
|
||||
HPEN OldPen;
|
||||
HPEN NewPen;
|
||||
|
||||
if (!currentgraph) return 0;
|
||||
wd = pWindowData(currentgraph);
|
||||
if (!wd) return 0;
|
||||
|
||||
MoveToEx(wd->hDC, x1, wd->Area.bottom - y1, NULL);
|
||||
NewPen = CreatePen( LType(wd->ColorIndex), 0, ColorTable[wd->ColorIndex] );
|
||||
OldPen = SelectObject(wd->hDC, NewPen);
|
||||
LineTo(wd->hDC, x2, wd->Area.bottom - y2);
|
||||
OldPen = SelectObject(wd->hDC, OldPen);
|
||||
DeleteObject( NewPen);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int WIN_Arc(int x0, int y0, int radius, double theta1, double theta2)
|
||||
/*
|
||||
* Notes:
|
||||
* Draws an arc of <radius> and center at (x0,y0) beginning at
|
||||
* angle theta1 (in rad) and ending at theta2
|
||||
*/
|
||||
{
|
||||
tpWindowData wd;
|
||||
HPEN OldPen;
|
||||
HPEN NewPen;
|
||||
int left, right, top, bottom;
|
||||
int xs, ys, xe, ye;
|
||||
int yb;
|
||||
int direction;
|
||||
double temp;
|
||||
double r;
|
||||
double dx0;
|
||||
double dy0;
|
||||
|
||||
if (!currentgraph) return 0;
|
||||
wd = pWindowData(currentgraph);
|
||||
if (!wd) return 0;
|
||||
|
||||
direction = AD_COUNTERCLOCKWISE;
|
||||
if (theta1 > theta2) {
|
||||
temp = theta1;
|
||||
theta1 = theta2;
|
||||
theta2 = temp;
|
||||
direction = AD_CLOCKWISE;
|
||||
}
|
||||
SetArcDirection( wd->hDC, direction);
|
||||
|
||||
// Geometrische Vorüberlegungen
|
||||
yb = wd->Area.bottom;
|
||||
left = x0 - radius;
|
||||
right = x0 + radius;
|
||||
top = y0 + radius;
|
||||
bottom = y0 - radius;
|
||||
|
||||
r = radius;
|
||||
dx0 = x0;
|
||||
dy0 = y0;
|
||||
xs = (dx0 + (r * cos(theta1)));
|
||||
ys = (dy0 + (r * sin(theta1)));
|
||||
xe = (dx0 + (r * cos(theta2)));
|
||||
ye = (dy0 + (r * sin(theta2)));
|
||||
|
||||
// Zeichnen
|
||||
NewPen = CreatePen( LType(wd->ColorIndex), 0, ColorTable[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);
|
||||
DeleteObject( NewPen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WIN_Text( char * text, int x, int y, int degrees)
|
||||
{
|
||||
tpWindowData wd;
|
||||
if (!currentgraph) return 0;
|
||||
wd = pWindowData(currentgraph);
|
||||
if (!wd) return 0;
|
||||
|
||||
SetTextColor( wd->hDC, ColorTable[wd->ColorIndex]);
|
||||
TextOut( wd->hDC, x, wd->Area.bottom - y - currentgraph->fontheight, text, strlen(text));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int WIN_DefineColor(int red, int green, int blue, int num)
|
||||
{
|
||||
// nix
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WIN_DefineLinestyle(int num, int mask)
|
||||
{
|
||||
// nix
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WIN_SetLinestyle(int style)
|
||||
{
|
||||
// nix
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WIN_SetColor( int color)
|
||||
{
|
||||
tpWindowData wd;
|
||||
if (!currentgraph) return 0;
|
||||
wd = pWindowData(currentgraph);
|
||||
if (!wd) return 0;
|
||||
|
||||
wd->ColorIndex = color % NumWinColors;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WIN_Update()
|
||||
{
|
||||
tpWindowData wd;
|
||||
if (!currentgraph) return 0;
|
||||
wd = pWindowData(currentgraph);
|
||||
if (!wd) return 0;
|
||||
|
||||
// Nach dem ersten absolvieren von Update() werden durch
|
||||
// FirstFlag wieder WM_PAINT-Botschaften bearbeitet.
|
||||
// Dies verhindert doppeltes Zeichnen beim Darstellen des Fensters.
|
||||
wd->FirstFlag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WIN_DiagramReady()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAS_WINDOWS */
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* Printing Routines for the IBM PC using MS Windows
|
||||
* Wolfgang Mües 27.10.97
|
||||
* Holger Vogt 07.12.01
|
||||
*/
|
||||
|
||||
#define STRICT
|
||||
#include "ngspice.h"
|
||||
|
||||
#ifdef HAS_WINDOWS
|
||||
|
||||
#include "graph.h"
|
||||
#include "ftedev.h"
|
||||
#include "ftedbgra.h"
|
||||
#pragma warn -dup
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include "suffix.h"
|
||||
#pragma hdrstop
|
||||
|
||||
// Typen
|
||||
typedef struct { // Extra Printdaten
|
||||
int ColorIndex; // Index auf die akt. Farbe
|
||||
int LineIndex; // Index auf den akt. Linientyp
|
||||
} tPrintData;
|
||||
typedef tPrintData * tpPrintData; // Zeiger darauf
|
||||
#define pPrintData(g) ((tpPrintData)(g->devdep))
|
||||
|
||||
// lokale Variablen
|
||||
static HFONT PlotFont = NULL; // Font-Merker
|
||||
static HFONT OldFont = NULL;
|
||||
#define NumLines 7 // Anzahl der LineStyles
|
||||
static int LineTable[NumLines]; // Speicher für die LineStyles
|
||||
static HDC PrinterDC = NULL; // Device Context
|
||||
#define NumPrintColors 2 // vordef. Farben
|
||||
static COLORREF ColorTable[NumPrintColors];// Speicher für die Farben
|
||||
static int PrinterWidth = 1000; // Breite des Papiers
|
||||
static int PrinterHeight = 1000; // Höhe des Papiers
|
||||
|
||||
/******************************************************************************
|
||||
Drucker-Initialisierung
|
||||
******************************************************************************/
|
||||
|
||||
void WPRINT_PrintInit(HWND hwnd)
|
||||
{
|
||||
// Parameter-Block
|
||||
PRINTDLG pd;
|
||||
|
||||
// Initialisieren
|
||||
pd.lStructSize = sizeof(PRINTDLG);
|
||||
pd.hwndOwner = hwnd;
|
||||
pd.hDevMode = NULL;
|
||||
pd.hDevNames = NULL;
|
||||
pd.hDC = NULL;
|
||||
pd.Flags = PD_PRINTSETUP;
|
||||
pd.nFromPage = 1;
|
||||
pd.nToPage = 1;
|
||||
pd.nMinPage = 0;
|
||||
pd.nMaxPage = 0;
|
||||
pd.nCopies = 1;
|
||||
pd.hInstance = NULL;
|
||||
pd.lCustData = 0;
|
||||
pd.lpfnPrintHook = NULL;
|
||||
pd.lpfnSetupHook = NULL;
|
||||
pd.lpPrintTemplateName = NULL;
|
||||
pd.lpSetupTemplateName = NULL;
|
||||
pd.hPrintTemplate = NULL;
|
||||
pd.hSetupTemplate = NULL;
|
||||
|
||||
// Default-Drucker initialisieren
|
||||
(void) PrintDlg( &pd);
|
||||
|
||||
// Speicher freigeben
|
||||
if( pd.hDevMode) GlobalFree( pd.hDevMode);
|
||||
if( pd.hDevNames) GlobalFree( pd.hDevNames);
|
||||
}
|
||||
|
||||
// Abort-Procedur zum Drucken
|
||||
BOOL CALLBACK WPRINT_Abort( HDC hdc, int iError)
|
||||
{
|
||||
// Multitasking
|
||||
WaitForIdle();
|
||||
|
||||
// Warten
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
WPRINT_Init() stellt die Verbindung zur Grafik her. Dazu gehört die Feststellung
|
||||
von
|
||||
dispdev->numlinestyles
|
||||
dispdev->numcolors
|
||||
dispdev->width
|
||||
dispdev->height
|
||||
|
||||
WPRINT_Init() gibt 0 zurück, falls kein Fehler auftrat.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
int WPRINT_Init( )
|
||||
{
|
||||
int pWidth;
|
||||
int pHeight;
|
||||
|
||||
// Printer-DC holen
|
||||
if (!PrinterDC) {
|
||||
|
||||
// Parameter-Block
|
||||
PRINTDLG pd;
|
||||
|
||||
// Initialisieren
|
||||
pd.lStructSize = sizeof(PRINTDLG);
|
||||
pd.hwndOwner = NULL;
|
||||
pd.hDevMode = NULL;
|
||||
pd.hDevNames = NULL;
|
||||
pd.hDC = NULL;
|
||||
pd.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC;
|
||||
pd.nFromPage = 1;
|
||||
pd.nToPage = 1;
|
||||
pd.nMinPage = 0;
|
||||
pd.nMaxPage = 0;
|
||||
pd.nCopies = 1;
|
||||
pd.hInstance = NULL;
|
||||
pd.lCustData = 0;
|
||||
pd.lpfnPrintHook = NULL;
|
||||
pd.lpfnSetupHook = NULL;
|
||||
pd.lpPrintTemplateName = NULL;
|
||||
pd.lpSetupTemplateName = NULL;
|
||||
pd.hPrintTemplate = NULL;
|
||||
pd.hSetupTemplate = NULL;
|
||||
|
||||
// Default-Drucker initialisieren
|
||||
(void) PrintDlg( &pd);
|
||||
|
||||
// Speicher freigeben
|
||||
if( pd.hDevMode) GlobalFree( pd.hDevMode);
|
||||
if( pd.hDevNames) GlobalFree( pd.hDevNames);
|
||||
|
||||
// DC holen
|
||||
PrinterDC = pd.hDC;
|
||||
if (!PrinterDC) return 1;
|
||||
|
||||
// Abmaße bestimmen
|
||||
PrinterWidth = GetDeviceCaps( PrinterDC, HORZRES);
|
||||
PrinterHeight = GetDeviceCaps( PrinterDC, VERTRES);
|
||||
pWidth = GetDeviceCaps( PrinterDC, HORZSIZE);
|
||||
pHeight = GetDeviceCaps( PrinterDC, VERTSIZE);
|
||||
|
||||
// Mapping Mode setzen (für Kreise)
|
||||
if ( pWidth > pHeight)
|
||||
// Querformat
|
||||
PrinterWidth = (PrinterHeight * pWidth) / pHeight;
|
||||
else
|
||||
// Hochformat
|
||||
PrinterHeight = (PrinterWidth * pHeight) / pWidth;
|
||||
|
||||
SetMapMode( PrinterDC, MM_ISOTROPIC);
|
||||
SetWindowExtEx( PrinterDC, PrinterWidth, PrinterHeight, NULL);
|
||||
SetViewportExtEx( PrinterDC, PrinterWidth, PrinterHeight, NULL);
|
||||
|
||||
// nicht höher als breit zeichnen
|
||||
if (pWidth < pHeight) {
|
||||
// Papier im Hochformat
|
||||
PrinterHeight = PrinterWidth;
|
||||
}
|
||||
|
||||
// Initialisierungen des Display-Descriptors
|
||||
dispdev->width = PrinterWidth;
|
||||
dispdev->height = PrinterHeight;
|
||||
dispdev->numlinestyles = NumLines;
|
||||
dispdev->numcolors = NumPrintColors;
|
||||
|
||||
// Farben initialisieren
|
||||
ColorTable[0] = RGB(255,255,255); // Weiß
|
||||
ColorTable[1] = RGB( 0, 0, 0); // Schwarz
|
||||
|
||||
// LineStyles initialisieren
|
||||
LineTable[0] = PS_SOLID;
|
||||
LineTable[1] = PS_DOT; // Gitter
|
||||
LineTable[2] = PS_SOLID; // Erste Linie
|
||||
LineTable[3] = PS_DOT; // Zweite Linie
|
||||
LineTable[4] = PS_DASH; // usw
|
||||
LineTable[5] = PS_DASHDOT;
|
||||
LineTable[6] = PS_DASHDOTDOT;
|
||||
|
||||
// Font
|
||||
if (!PlotFont) {
|
||||
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);
|
||||
}
|
||||
// fertig
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
WPRINT_NewViewport() öffnet den Drucker
|
||||
|
||||
WPRINT_NewViewport() gibt 0 zurück, falls erfolgreich
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
int WPRINT_NewViewport( GRAPH * graph)
|
||||
{
|
||||
TEXTMETRIC tm;
|
||||
tpPrintData pd;
|
||||
DOCINFO di;
|
||||
|
||||
// Parameter testen
|
||||
if (!graph) return 1;
|
||||
|
||||
// Initialisiere, falls noch nicht geschehen
|
||||
if (WPRINT_Init() != 0) {
|
||||
externalerror("Can't initialize Printer.");
|
||||
return(1);
|
||||
}
|
||||
|
||||
// Device dep. Info allocieren
|
||||
pd = calloc(1, sizeof(tPrintData));
|
||||
if (!pd) return 1;
|
||||
graph->devdep = (char *)pd;
|
||||
|
||||
// Setze den Color-Index
|
||||
pd->ColorIndex = 0;
|
||||
|
||||
// Font setzen
|
||||
OldFont = SelectObject( PrinterDC, PlotFont);
|
||||
|
||||
// Font-Parameter abfragen
|
||||
if (GetTextMetrics( PrinterDC, &tm)) {
|
||||
graph->fontheight = tm.tmHeight;
|
||||
graph->fontwidth = tm.tmAveCharWidth;
|
||||
}
|
||||
|
||||
// Setze den Linien-Index
|
||||
pd->LineIndex = 0;
|
||||
|
||||
// Viewport-Parameter setzen
|
||||
graph->viewport.height = PrinterHeight;
|
||||
graph->viewport.width = PrinterWidth;
|
||||
|
||||
// Absolut-Parameter setzen
|
||||
graph->absolute.xpos = 0;
|
||||
graph->absolute.ypos = 0;
|
||||
graph->absolute.width = PrinterWidth;
|
||||
graph->absolute.height = PrinterHeight;
|
||||
|
||||
// Druckauftrag anmelden
|
||||
di.cbSize = sizeof( DOCINFO);
|
||||
di.lpszDocName = graph->plotname;
|
||||
di.lpszOutput = NULL;
|
||||
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,
|
||||
strlen(graph->plotname));
|
||||
SetTextAlign( PrinterDC, align);
|
||||
}
|
||||
|
||||
// fertig
|
||||
return(0);
|
||||
}
|
||||
|
||||
int WPRINT_Close()
|
||||
{
|
||||
if (PrinterDC) {
|
||||
EndPage( PrinterDC);
|
||||
EndDoc( PrinterDC);
|
||||
if (OldFont) {
|
||||
SelectObject( PrinterDC, OldFont);
|
||||
OldFont = NULL;
|
||||
}
|
||||
DeleteObject( PlotFont);
|
||||
DeleteDC( PrinterDC);
|
||||
PrinterDC = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int WPRINT_Clear()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int WPRINT_DrawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
tpPrintData pd;
|
||||
HPEN OldPen;
|
||||
HPEN NewPen;
|
||||
int ColIndex;
|
||||
|
||||
if (!currentgraph) return 0;
|
||||
pd = pPrintData(currentgraph);
|
||||
if (!pd) return 0;
|
||||
|
||||
// Farben/Dicke
|
||||
ColIndex = pd->ColorIndex;
|
||||
if (ColIndex > 1)
|
||||
ColIndex = 1;
|
||||
|
||||
MoveToEx(PrinterDC, x1, PrinterHeight - y1, NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
int WPRINT_Arc(int x0, int y0, int radius, double theta1, double theta2)
|
||||
/*
|
||||
* Notes:
|
||||
* Draws an arc of <radius> and center at (x0,y0) beginning at
|
||||
* angle theta1 (in rad) and ending at theta2
|
||||
*/
|
||||
{
|
||||
tpPrintData pd;
|
||||
HPEN OldPen;
|
||||
HPEN NewPen;
|
||||
int left, right, top, bottom;
|
||||
int xs, ys, xe, ye;
|
||||
int yb;
|
||||
int direction;
|
||||
int ColIndex;
|
||||
double temp;
|
||||
double r;
|
||||
double dx0;
|
||||
double dy0;
|
||||
|
||||
if (!currentgraph) return 0;
|
||||
pd = pPrintData(currentgraph);
|
||||
if (!pd) return 0;
|
||||
|
||||
ColIndex = pd->ColorIndex;
|
||||
if (ColIndex > 1)
|
||||
ColIndex = 1;
|
||||
|
||||
direction = AD_COUNTERCLOCKWISE;
|
||||
if (theta1 > theta2) {
|
||||
temp = theta1;
|
||||
theta1 = theta2;
|
||||
theta2 = temp;
|
||||
direction = AD_CLOCKWISE;
|
||||
}
|
||||
SetArcDirection( PrinterDC, direction);
|
||||
|
||||
// Geometrische Vorüberlegungen
|
||||
yb = PrinterHeight;
|
||||
left = x0 - radius;
|
||||
right = x0 + radius;
|
||||
top = y0 + radius;
|
||||
bottom = y0 - radius;
|
||||
|
||||
r = radius;
|
||||
dx0 = x0;
|
||||
dy0 = y0;
|
||||
xs = (dx0 + (r * cos(theta1)));
|
||||
ys = (dy0 + (r * sin(theta1)));
|
||||
xe = (dx0 + (r * cos(theta2)));
|
||||
ye = (dy0 + (r * sin(theta2)));
|
||||
|
||||
// Zeichnen
|
||||
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);
|
||||
OldPen = SelectObject(PrinterDC, OldPen);
|
||||
DeleteObject( NewPen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WPRINT_Text( char * text, int x, int y, int degrees)
|
||||
{
|
||||
tpPrintData pd;
|
||||
int ColIndex;
|
||||
|
||||
if (!currentgraph) return 0;
|
||||
pd = pPrintData(currentgraph);
|
||||
if (!pd) return 0;
|
||||
|
||||
ColIndex = pd->ColorIndex;
|
||||
if (ColIndex > 1) {
|
||||
ColIndex = 1;
|
||||
}
|
||||
|
||||
SetTextColor( PrinterDC, ColorTable[ColIndex]);
|
||||
TextOut( PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, text, strlen(text));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int WPRINT_DefineColor(int red, int green, int blue, int num)
|
||||
{
|
||||
// nix
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WPRINT_DefineLinestyle(int num, int mask)
|
||||
{
|
||||
// nix
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WPRINT_SetLinestyle(int style)
|
||||
{
|
||||
tpPrintData pd;
|
||||
if (!currentgraph) return 0;
|
||||
pd = pPrintData(currentgraph);
|
||||
if (!pd) return 0;
|
||||
|
||||
pd->LineIndex = style % NumLines;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WPRINT_SetColor( int color)
|
||||
{
|
||||
tpPrintData pd;
|
||||
if (!currentgraph) return 0;
|
||||
pd = pPrintData(currentgraph);
|
||||
if (!pd) return 0;
|
||||
|
||||
pd->ColorIndex = color;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WPRINT_Update()
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int WPRINT_DiagramReady()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAS_WINDOWS */
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* I/O Redirection für Spice 3F4 unter Win32s
|
||||
Autor: Wolfgang Mües
|
||||
Stand: 21.05.95
|
||||
*/
|
||||
|
||||
#ifndef W_STDIO_H
|
||||
#define W_STDIO_H
|
||||
#include <stdio.h> // originale Definitionen
|
||||
#undef getc(f) // alte macros zurücknehmen
|
||||
#undef putc(c,f)
|
||||
#undef ungetc(c,f)
|
||||
#undef getchar()
|
||||
#undef putchar(c)
|
||||
#undef feof(f)
|
||||
#undef ferror(f)
|
||||
|
||||
|
||||
// -------------------------------<forwards>-----------------------------------
|
||||
|
||||
int f_c_l_o_s_e( FILE * __stream);
|
||||
int f_f_l_u_s_h( FILE * __stream);
|
||||
int fg_e_t_c( FILE * __stream);
|
||||
int f_g_e_t_p_o_s( FILE * __stream, fpos_t * __pos);
|
||||
char * fg_e_t_s(char * __s, int __n, FILE * __stream);
|
||||
int fp_r_i_n_t_f(FILE * __stream, const char * __format, ...);
|
||||
int fp_u_t_c(int __c, FILE * __stream);
|
||||
int fp_u_t_s(const char * __s, FILE * __stream);
|
||||
size_t f_r_e_a_d(void * __ptr, size_t __size, size_t __n, FILE * __stream);
|
||||
FILE * f_r_e_o_p_e_n(const char * __path, const char * __mode, FILE * __stream);
|
||||
int fs_c_a_n_f(FILE * __stream, const char * __format, ...);
|
||||
int f_s_e_e_k(FILE * __stream, long __offset, int __whence);
|
||||
int f_s_e_t_p_o_s(FILE * __stream, const fpos_t*__pos);
|
||||
long f_t_e_l_l(FILE * __stream);
|
||||
size_t f_w_r_i_t_e(const void * __ptr, size_t __size, size_t __n, FILE * __stream);
|
||||
char * g_e_t_s(char * __s);
|
||||
void p_e_r_r_o_r(const char * __s);
|
||||
int p_r_i_n_t_f(const char * __format, ...);
|
||||
int p_u_t_s(const char * __s);
|
||||
int s_c_a_n_f(const char * __format, ...);
|
||||
int ung_e_t_c(int __c, FILE * __stream);
|
||||
int vfp_r_i_n_t_f(FILE * __stream, const char * __format, void * __arglist);
|
||||
//int vfs_c_a_n_f(FILE * __stream, const char * __format, void * __arglist);
|
||||
int vp_r_i_n_t_f(const char * __format, void * __arglist);
|
||||
//int vs_c_a_n_f(const char * __format, void * __arglist);
|
||||
int r_e_a_d(int fd, char * __buf, int __n);
|
||||
int g_e_t_c(FILE * __fp);
|
||||
int g_e_t_char(void);
|
||||
int p_u_t_char(const int __c);
|
||||
int p_u_t_c(const int __c, FILE * __fp);
|
||||
int f_e_o_f(FILE * __fp);
|
||||
int f_e_r_r_o_r(FILE * __fp);
|
||||
int fg_e_t_char(void);
|
||||
int fp_u_t_char(int __c);
|
||||
|
||||
// ------------------------------<neue macros>---------------------------------
|
||||
|
||||
#define fclose f_c_l_o_s_e
|
||||
#define fflush f_f_l_u_s_h
|
||||
#define fgetc fg_e_t_c
|
||||
#define fgetpos f_g_e_t_p_o_s
|
||||
#define fgets fg_e_t_s
|
||||
#define fprintf fp_r_i_n_t_f
|
||||
#define fputc fp_u_t_c
|
||||
#define fputs fp_u_t_s
|
||||
#define fread f_r_e_a_d
|
||||
#define afreopen f_r_e_o_p_e_n // hvogt 10.05.2000
|
||||
#define fscanf fs_c_a_n_f
|
||||
#define fseek f_s_e_e_k
|
||||
#define fsetpos f_s_e_t_p_o_s
|
||||
#define ftell f_t_e_l_l
|
||||
#define fwrite f_w_r_i_t_e
|
||||
#define gets g_e_t_s
|
||||
#define perror p_e_r_r_o_r
|
||||
#define printf p_r_i_n_t_f
|
||||
#define puts p_u_t_s
|
||||
#define scanf s_c_a_n_f
|
||||
#define ungetc ung_e_t_c
|
||||
#define vfprintf vfp_r_i_n_t_f
|
||||
//#define vfscanf vfs_c_a_n_f
|
||||
#define vprintf vp_r_i_n_t_f
|
||||
//#define vscanf vs_c_a_n_f
|
||||
#define read r_e_a_d
|
||||
#define getc g_e_t_c
|
||||
#define getchar g_e_t_char
|
||||
#define putchar p_u_t_char
|
||||
#define putc p_u_t_c
|
||||
#define feof f_e_o_f
|
||||
#define ferror f_e_r_r_o_r
|
||||
#define fgetchar fg_e_t_char
|
||||
#define fputchar fp_u_t_char
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// #include "io_special.h"
|
||||
|
||||
#endif /* W_STDIO_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue