7 changed files with 2452 additions and 0 deletions
-
11src/frontend/wdisp/Makefile.am
-
16src/frontend/wdisp/ftegraf.h
-
12src/frontend/wdisp/makedefs
-
542src/frontend/wdisp/windisp.c
-
451src/frontend/wdisp/winprint.c
-
97src/include/wstdio.h
-
1323src/winmain.c
@ -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 */ |
|||
|
|||
1323
src/winmain.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue