⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.c

📁 书名:C语言科学与艺术,以前交钱下载的
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * File: graphics.c * Version: 3.1 * Last modified on Fri Feb 24 19:42:15 1995 by eroberts * ----------------------------------------------------- * This file implements the graphics.h and extgraph.h interfaces * for the Macintosh using THINK's Lightspeed C. *//* * General implementation notes * ---------------------------- * This implementation is relatively complex for two reasons. * The first source of complexity is that windows on the * Macintosh are dynamically repositioned, obscured, and * reexposed.  When these events occur, the drawing in the * window needs to be repainted.  Thus, it is not sufficient * to have the drawing package simply issue the appropriate * QuickDraw procedures directly to the screen.  This * implementation solves the problem by rendering the image * to an offscreen bitmap and then repainting the image from * that copy whenever update events occur. * * The second problem, which is indeed more severe, is that * that is much more easily understood by experts than by * novices.  In a traditional Macintosh application, the * main program is coded as an "event loop," which * continually polls the event manager to see if any activity * is necessary.  This strategy runs counter to the more * conventional view of a main program as the highest level * in the problem decomposition.  In the context of teaching * programming, we want the main program and its subprograms * to draw the figures -- a strategy which is not easy to * reconcile with the standard Macintosh approach.  This * implementation solves this problem by patching in a call * to an update procedure as part of the event loop embedded * in the console input mechanism. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <console.h>#include <math.h>#include <time.h>#include <Traps.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 * ConsoleLines     -- Console lines * ConsoleHeight    -- Estimate of console height (inches) * BottomMargin     -- Minimum bottom margin (inches) * RightMargin      -- Minimum right margin (inches) * WindowSeparation -- Minimum window separation (inches) * TitleBarPixels   -- Pixel height of title bar * DefaultFont      -- Font used to implement "Default" font * DefaultSize      -- Initial point size for text * MaxColors        -- Maximum number of color names allowed * MinColors        -- Minimum number of colors the device must support * CheckForColor    -- TRUE if abstraction should check for color memory */#define DesiredWidth       7.0#define DesiredHeight      4.0#define ConsoleLines       8#define ConsoleHeight      1.1#define BottomMargin       0.05#define RightMargin        0.05#define WindowSeparation   0.10#define TitleBarPixels    20#define DefaultFont "Geneva"#define DefaultSize 10#define MaxColors       256#define MinColors        16#define CheckForColor FALSE/* * Other constants * --------------- * LargeInt -- Used to signify out of range values * Epsilon  -- Small arithmetic offset to reduce aliasing/banding * Pi       -- Mathematical constant pi */#define LargeInt 16000#define Epsilon  0.00000000001#define Pi       3.1415926535/* * 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: 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;/* * Global variables * ---------------- * initialized   -- TRUE if initialization has been done * windowTitle   -- Current window title (initialized statically) * consoleFile   -- FILE * for console (saved to allow redirection) * gWindow       -- Window pointer for graphics window * osWindow      -- Offscreen window pointer for rendering * xResolution   -- Horizontal resolution of screen (dots per inch) * yResolution   -- Vertical resolution of screen (dots per inch) * windowWidth   -- Width of graphics window * windowHeight  -- Height of graphics window * regionState   -- Current state of the region * regionDensity -- Fill density to apply to region * mouseState    -- State of mouse as tracked by event handler * colorTable    -- Table of defined colors * nColors       -- Number of defined colors * colorOK       -- TRUE if color port successfully initialized * checkMemory   -- TRUE if application should check color memory * 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 string windowTitle = "Graphics Window";static FILE consoleFile;static WindowPeek gWindow, osWindow;static short xResolution, yResolution;static double windowWidth = DesiredWidth;static double windowHeight = DesiredHeight;static regionStateT regionState;static double regionDensity;static bool mouseState;static colorEntryT colorTable[MaxColors];static int nColors;static bool colorOK;static bool checkMemory = CheckForColor;static graphicsStateT stateStack;static double cx, cy;static bool eraseMode;static string textFont;static int textStyle;static int pointSize;static int penColor;/* * 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. */static Pattern fillList[] = {    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },    { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },    { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },    { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },};#define NFills (sizeof fillList / sizeof fillList[0])/* Private function prototypes */static void InitCheck(void);static void InitGraphicsState(void);static void EraseWindow(void);static void CreateGraphicsWindow(void);static bool CreateColorWindow(Rect *bounds);static bool CreateBWWindow(Rect *bounds);static void PrepareToDraw(void);static void PrepareToDrawText(void);static void DisplayLine(double x, double y, double dx, double dy);static void DisplayArc(double x, double y, 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 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 UpdateRect(Rect *rp);static StringPtr PascalString(string cstr);static int GetFontNumber(string fontName);static void InitColors(void);static bool ShouldBeWhite(void);static void CheckColorMemory(void);static int FindColorName(string name);static void PatchEventHandler(void);static long FindSystemTrap(short trap);static void MyEventHandler(EventRecord *ep);static void DoUpdateDisplay(void);static bool StringMatch(string s1, string s2);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 double Degrees(double radians);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 Round(double x);static int Min(int x, int y);static int Max(int x, int y);static double MinF(double x, double y);static double MaxF(double x, double y);/* Exported entries *//* Section 1 -- Basic functions from graphics.h */void InitGraphics(void){    if (initialized) {        EraseWindow();    } else {        initialized = TRUE;        ProtectVariable(stateStack);        ProtectVariable(windowTitle);        ProtectVariable(textFont);        InitColors();        CreateGraphicsWindow();        PatchEventHandler();    }    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 density){    GrafPtr saveWindow;    InitCheck();    if (regionState != NoRegion) {        Error("Region is already in progress");    }    if (density < 0 || density > 1) {        Error("Density for regions must be between 0 and 1");    }    regionState = RegionStarting;    regionDensity = density;    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    OpenRgn();    SetPort(saveWindow);}void EndFilledRegion(void){    RgnHandle region;    GrafPtr saveWindow;    int px;    InitCheck();    switch (regionState) {      case NoRegion:        Error("EndFilledRegion without StartFilledRegion");      case RegionStarting:        regionState = NoRegion;        return;      case RegionActive: case PenHasMoved:        regionState = NoRegion;        break;    }    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDraw();    region = NewRgn();    if (region == NULL) Error("EndFilledRegion: Can't create region");    CloseRgn(region);    UpdateRect(&(*region)->rgnBBox);    px = regionDensity * (NFills - 1) + 0.5 - Epsilon;    if (eraseMode || ShouldBeWhite()) px = 0;    FillRgn(region, ((Pattern *) fillList) + px);    SetPort(saveWindow);    DisposeRgn(region);}/* 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);}double TextStringWidth(string text){    Rect rect;    GrafPtr saveWindow;    InitCheck();    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDrawText();    SetTextBB(&rect, cx, cy, text);    SetPort(saveWindow);    return (InchesX(RectWidth(&rect)));}void SetFont(string font){    InitCheck();    if (GetFontNumber(font) != 0) {        textFont = CopyString(font);    }}string GetFont(void){    InitCheck();    return (CopyString(textFont));}void SetPointSize(int size){    InitCheck();    pointSize = size;}int GetPointSize(void){    InitCheck();    return (pointSize);}void SetStyle(int style){    InitCheck();    textStyle = style;}int GetStyle(void){    InitCheck();    return (textStyle);}double GetFontAscent(void){    FontInfo fInfo;    GrafPtr saveWindow;    InitCheck();    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDrawText();    GetFontInfo(&fInfo);    SetPort(saveWindow);    return (InchesY(fInfo.ascent));}double GetFontDescent(void){    FontInfo fInfo;    GrafPtr saveWindow;    InitCheck();    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDrawText();    GetFontInfo(&fInfo);    SetPort(saveWindow);    return (InchesY(fInfo.descent));}double GetFontHeight(void){    FontInfo fInfo;    GrafPtr saveWindow;    InitCheck();    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDrawText();    GetFontInfo(&fInfo);    SetPort(saveWindow);    return (InchesY(fInfo.ascent + fInfo.descent + fInfo.leading));}/* Section 5 -- Mouse support */double GetMouseX(void){    GrafPtr saveWindow;    Point pt;    InitCheck();    GetPort(&saveWindow);    SetPort((WindowPtr) gWindow);    GetMouse(&pt);    SetPort(saveWindow);    return (InchesX(pt.h));}double GetMouseY(void){    GrafPtr saveWindow;    Point pt;    InitCheck();    GetPort(&saveWindow);    SetPort((WindowPtr) gWindow);    GetMouse(&pt);    SetPort(saveWindow);    return (windowHeight - InchesY(pt.v));}bool MouseButtonIsDown(void){    InitCheck();    return (Button());}void WaitForMouseDown(void){    InitCheck();    mouseState = Button();    while (!mouseState) {        UpdateDisplay();    }}void WaitForMouseUp(void){    InitCheck();    mouseState = Button();    while (mouseState) {        UpdateDisplay();    }}/* Section 6 -- Color support */bool HasColor(void){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -