📄 graphics.c
字号:
/* * File: graphics.c * Version: 3.0 * Last modified on Wed Sep 21 23:53:53 1994 by eroberts * ----------------------------------------------------- * This file implements the graphics.h and extgraph.h interfaces * for the Borland/Windows platform. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include <conio.h>#include <windows.h>#include <time.h>#include "genlib.h"#include "gcalloc.h"#include "strlib.h"#include "extgraph.h"/* * Parameters * ---------- * DesiredWidth -- Desired width of the graphics window * DesiredHeight -- Desired height of the graphics window * DefaultSize -- Default point size * MaxTitle -- Maximum window title length * MaxFontName -- Maximum font name length * MaxFonts -- Maximum number of fonts * LeftMargin -- Margin from left of screen to both windows * RightMargin -- Minimum margin to right of windows * TopMargin -- Margin from top of screen to graphics window * BottomMargin -- Minimum margin from bottom of screen to console window * WindowSep -- Separation between graphics and console windows * ConsoleHeight -- Height of the console window (pixels) * MinConsoleScale -- Smallest acceptable scale factor for the console * PStartSize -- Starting size for polygon (must be greater than 1) * MaxColors -- Maximum number of color names allowed * MinColors -- Minimum number of colors the device must support * GWClassName -- Class name of the graphics window * DefaultFont -- Font that serves as the "Default" font */#define DesiredWidth 7.0#define DesiredHeight 4.0#define DefaultSize 12#define MaxTitle 75#define MaxFontName 50#define MaxFonts 100#define LeftMargin 10#define RightMargin 25#define TopMargin 2#define BottomMargin 30#define WindowSep 5#define ConsoleHeight 110#define MinConsoleScale 0.8#define PStartSize 50#define MaxColors 256#define MinColors 16#define GWClassName "Graphics Window"#define DefaultFont "System"/* * Other constants * --------------- * LargeInt -- Integer too large for a coordinate value * Epsilon -- Small arithmetic offset to reduce aliasing/banding * Pi -- Mathematical constant pi * AnyButton -- Union of all mouse buttons */#define LargeInt 16000#define Epsilon 0.00000000001#define Pi 3.1415926535#define AnyButton (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)/* * Type: graphicsStateT * -------------------- * This structure holds the variables that make up the graphics state. */typedef struct graphicsStateT { double cx, cy; string font; int size; int style; bool erase; int color; struct graphicsStateT *link;} *graphicsStateT;/* * Type: fontEntryT * ---------------- * This structure holds the data for a font. */typedef struct { string name; int size, style; int points, ascent, descent, height; HFONT font;} fontEntryT;/* * Type: regionStateT * ------------------ * The region assembly process has the character of a finite state * machine with the following four states: * * NoRegion Region has not yet been started * RegionStarting Region is started but no line segments yet * RegionActive First line segment appears * PenHasMoved Pen has moved during definition * * The current state determines whether other operations are legal * at that point. */typedef enum { NoRegion, RegionStarting, RegionActive, PenHasMoved} regionStateT;/* * Type: colorEntryT * ----------------- * This type is used for the entries in the color table. */typedef struct { string name; double red, green, blue;} colorEntryT;/* * Static table: fillList * ---------------------- * This table contains the bitmap patterns for the various density * values. Adding more patterns to this list increases the * precision with which the client can control fill patterns. * Note that this bitmap is inverted from that used on most * systems, with 0 indicating foreground and 1 indicating background. */static short fillList[][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD }, { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA }, { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },};#define NFills (sizeof fillList / sizeof fillList[0])/* * Global variables * ---------------- * initialized -- TRUE if initialization has been done * pauseOnExit -- TRUE if library should pause when exiting * consoleWindow -- Window handle for console window * graphicsWindow -- Window handoe for graphics window * gdc -- Graphics DC (screen) * osdc -- Offscreen DC (memory backup) * osbits -- Offscreen bitmap * drawPen -- Pen used for drawing * erasePen -- Pen used for erasing * nullPen -- Pen used for filling * drawColor -- Color used for drawing * eraseColor -- Color used for erasing * windowTitle -- Current window title (initialized statically) * xResolution -- Horizontal resolution of screen (dots per inch) * yResolution -- Vertical resolution of screen (dots per inch) * windowWidth -- Width of graphics window (inches) * windowHeight -- Height of graphics window (inches) * pixelWidth -- Width of graphics window (pixels) * pixelHeight -- Height of graphics window (pixels) * fontTable -- Table of stored fonts * nFonts -- Number of fonts in fontTable * currentFont -- Index of current font in fontTable * regionState -- Current state of the region * regionDensity -- Fill density to apply to region * polygonPoints -- Array of points used in current region * nPolygonPoints -- Number of active points * polygonSize -- Number of allocated points * polygonBounds -- Bounding box of polygon * colorTable -- Table of defined colors * nColors -- Number of defined colors * previousColor -- Last color index set * stateStack -- Stack of graphicStateT blocks * cx, cy -- Current coordinates | These * eraseMode -- Setting of erase flag | variables * textFont -- Current font | consititute * textStyle -- Current style | the current * pointSize -- Current point size | graphics * penColor -- Color of pen | state */static bool initialized = FALSE;static bool pauseOnExit = TRUE;static HWND consoleWindow, graphicsWindow;static HDC gdc, osdc;static HBITMAP osBits;static HPEN drawPen, erasePen, nullPen;static COLORREF drawColor, eraseColor;static PAINTSTRUCT ps;static string windowTitle = "Graphics Window";static double xResolution, yResolution;static double windowWidth = DesiredWidth;static double windowHeight = DesiredHeight;static int pixelWidth, pixelHeight;static fontEntryT fontTable[MaxFonts];static int nFonts;static int currentFont;static regionStateT regionState;static double regionDensity;static POINT *polygonPoints;static int nPolygonPoints;static int polygonSize;static RECT polygonBounds;static HBITMAP fillBitmaps[NFills];static colorEntryT colorTable[MaxColors];static int nColors;static int previousColor;static graphicsStateT stateStack;static double cx, cy;static bool eraseMode;static string textFont;static int textStyle;static int pointSize;static int penColor;static int mouseX, mouseY;static bool mouseButton = FALSE;/* Private function prototypes */static void InitCheck(void);static void InitGraphicsState(void);static void InitDisplay(void);static void InitDrawingTools(void);static void DisplayExit(void);static HWND FindConsoleWindow(void);static BOOL CALLBACK EnumerateProc(HWND window, LPARAM clientData);static void RegisterWindowClass(void);static LONG FAR PASCAL GraphicsEventProc(HWND w, UINT msg, WPARAM p1, LPARAM p2);static void DoUpdate(void);static void DisplayClear(void);static void PrepareToDraw(void);static void DisplayLine(double x, double y, double dx, double dy);static void DisplayArc(double xc, double yc, double rx, double ry, double start, double sweep);static void RenderArc(double x, double y, double rx, double ry, double start, double sweep);static void DisplayText(double x, double y, string text);static void DisplayFont(string font, int size, int style);static int FindExistingFont(string name, int size, int style);static void SetLineBB(RECT *rp, double x, double y, double dx, double dy);static void SetArcBB(RECT *rp, double xc, double yc, double rx, double ry, double start, double sweep);static void SetTextBB(RECT *rp, double x, double y, string text);static void StartPolygon(void);static void AddSegment(int x0, int y0, int x1, int y1);static void DisplayPolygon(void);static void AddPolygonPoint(int x, int y);static void InitColors(void);static int FindColorName(string name);static bool StringMatch(string s1, string s2);static bool PrefixMatch(string prefix, string str);static int RectWidth(RECT *rp);static int RectHeight(RECT *rp);static void SetRectFromSize(RECT *rp, int x, int y, int width, int height);static double Radians(double degrees);static int Round(double x);static double InchesX(int x);static double InchesY(int y);static int PixelsX(double x);static int PixelsY(double y);static int ScaleX(double x);static int ScaleY(double y);static int Min(int x, int y);static int Max(int x, int y);/* Exported entries *//* Section 1 -- Basic functions from graphics.h */void InitGraphics(void){ if (!initialized) { initialized = TRUE; ProtectVariable(stateStack); ProtectVariable(windowTitle); ProtectVariable(textFont); InitColors(); InitDisplay(); } DisplayClear(); InitGraphicsState();}void MovePen(double x, double y){ InitCheck(); if (regionState == RegionActive) regionState = PenHasMoved; cx = x; cy = y;}void DrawLine(double dx, double dy){ InitCheck(); switch (regionState) { case NoRegion: DisplayLine(cx, cy, dx, dy); break; case RegionStarting: case RegionActive: DisplayLine(cx, cy, dx, dy); regionState = RegionActive; break; case PenHasMoved: Error("Region segments must be contiguous"); } cx += dx; cy += dy;}void DrawArc(double r, double start, double sweep){ DrawEllipticalArc(r, r, start, sweep);}double GetWindowWidth(void){ InitCheck(); return (windowWidth);}double GetWindowHeight(void){ InitCheck(); return (windowHeight);}double GetCurrentX(void){ InitCheck(); return (cx);}double GetCurrentY(void){ InitCheck(); return (cy);}/* Section 2 -- Elliptical arcs */void DrawEllipticalArc(double rx, double ry, double start, double sweep){ double x, y; InitCheck(); x = cx + rx * cos(Radians(start + 180)); y = cy + ry * sin(Radians(start + 180)); switch (regionState) { case NoRegion: DisplayArc(x, y, rx, ry, start, sweep); break; case RegionStarting: case RegionActive: RenderArc(x, y, rx, ry, start, sweep); regionState = RegionActive; break; case PenHasMoved: Error("Region segments must be contiguous"); } cx = x + rx * cos(Radians(start + sweep)); cy = y + ry * sin(Radians(start + sweep));}/* Section 3 -- Graphical structures */void StartFilledRegion(double grayScale){ InitCheck(); if (regionState != NoRegion) { Error("Region is already in progress"); } if (grayScale < 0 || grayScale > 1) { Error("Gray scale for regions must be between 0 and 1"); } regionState = RegionStarting; regionDensity = grayScale; StartPolygon();}void EndFilledRegion(void){ InitCheck(); if (regionState == NoRegion) { Error("EndFilledRegion without StartFilledRegion"); } DisplayPolygon(); regionState = NoRegion;}/* Section 4 -- String functions */void DrawTextString(string text){ InitCheck(); if (regionState != NoRegion) { Error("Text strings are illegal inside a region"); } DisplayText(cx, cy, text); cx += TextStringWidth(text);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -