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

📄 graphics.c

📁 书名:C语言科学与艺术,以前交钱下载的
💻 C
📖 第 1 页 / 共 3 页
字号:
    InitCheck();    return (colorOK);}void SetPenColor(string color){    int cindex;    InitCheck();    if (checkMemory && !StringMatch(color, "Black")                    && !StringMatch(color, "White")) {        CheckColorMemory();        checkMemory = FALSE;    }    cindex = FindColorName(color);    if (cindex == -1) Error("Undefined color: %s", color);    penColor = cindex;}string GetPenColor(void){    InitCheck();    return (colorTable[penColor].name);}void DefineColor(string name,                 double red, double green, double blue){    int cindex;    InitCheck();    if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1) {        Error("DefineColor: All color intensities must be between 0 and 1");    }    cindex = FindColorName(name);    if (cindex == -1) {        if (nColors == MaxColors) Error("DefineColor: Too many colors");        cindex = nColors++;    }    colorTable[cindex].name = CopyString(name);    colorTable[cindex].red = red;    colorTable[cindex].green = green;    colorTable[cindex].blue = blue;}/* Section 7 -- Miscellaneous functions */void SetEraseMode(bool mode){    InitCheck();    eraseMode = mode;}bool GetEraseMode(void){    InitCheck();    return (eraseMode);}void SetWindowTitle(string title){    windowTitle = CopyString(title);    if (initialized) {        SetWTitle((WindowPtr) gWindow, PascalString(title));    }}string GetWindowTitle(void){    return (CopyString(windowTitle));}/* * Implementation notes: UpdateDisplay * ----------------------------------- * This implementation of this function is entirely dependent * on the implementation of the console.h interface.  Calling * the I/O event procedure for the console when cnt is 0 and raw * mode is on has the effect of responding to one pending event * without performing any I/O operations.  Repeating this call * as long as there are events therefore clears the event queue, * which will end up responding to any pending update events. */void UpdateDisplay(void){    EventRecord event;    int cnt;    InitCheck();    cnt = consoleFile.cnt;    consoleFile.cnt = 0;    csetmode(C_RAW, &consoleFile);    while (EventAvail(everyEvent, &event) || event.what != nullEvent) {        (void) consoleFile.proc(stdin, 0);    }    consoleFile.cnt = cnt;    csetmode(C_ECHO, &consoleFile);}void Pause(double seconds){    long dummy;    UpdateDisplay();    Delay(seconds * CLOCKS_PER_SEC, &dummy);}void ExitGraphics(void){    console_options.pause_atexit = FALSE;    exit(0);}void SaveGraphicsState(void){    graphicsStateT sb;    InitCheck();    sb = New(graphicsStateT);    sb->cx = cx;    sb->cy = cy;    sb->font = textFont;    sb->size = pointSize;    sb->style = textStyle;    sb->erase = eraseMode;    sb->color = penColor;    sb->link = stateStack;    stateStack = sb;}void RestoreGraphicsState(void){    graphicsStateT sb;    InitCheck();    if (stateStack == NULL) {        Error("RestoreGraphicsState called before SaveGraphicsState");    }    sb = stateStack;    cx = sb->cx;    cy = sb->cy;    textFont = sb->font;    pointSize = sb->size;    textStyle = sb->style;    eraseMode = sb->erase;    penColor = sb->color;    stateStack = sb->link;    FreeBlock(sb);}double GetFullScreenWidth(void){    GrafPtr wPort;    short xRes, yRes;    GetWMgrPort(&wPort);    ScreenRes(&xRes, &yRes);    return ((double) RectWidth(&wPort->portRect) / xRes);}double GetFullScreenHeight(void){    GrafPtr wPort;    short xRes, yRes;    GetWMgrPort(&wPort);    ScreenRes(&xRes, &yRes);    return ((double) RectHeight(&wPort->portRect) / yRes);}void SetWindowSize(double width, double height){    if (initialized) return;    windowWidth = width;    windowHeight = height;}double GetXResolution(void){    short xRes, yRes;    if (initialized) {        return (xResolution);    } else {        ScreenRes(&xRes, &yRes);        return (xRes);    }}double GetYResolution(void){    short xRes, yRes;    if (initialized) {        return (yResolution);    } else {        ScreenRes(&xRes, &yRes);        return (yRes);    }}/* Private functions *//* * Function: InitCheck * Usage: InitCheck(); * ------------------- * This function merely ensures that the package has been * initialized before the client functions are called. */static void InitCheck(void){    if (!initialized) Error("InitGraphics has not been called");}/* * Function: InitGraphicsState * Usage: InitGraphicsState(); * --------------------------- * This function initializes the graphics state elements to * their default values. */static void InitGraphicsState(void){    cx = cy = 0;    eraseMode = FALSE;    textFont = "Default";    pointSize = DefaultSize;    textStyle = Normal;    stateStack = NULL;    regionState = NoRegion;    SetPenColor("Black");}/* * Function: EraseWindow * Usage: EraseWindow(); * --------------------- * This function erases all of the offscreen memory bits, * thereby clearing the screen image.  Note that the portBits * array is typically larger than a Macintosh segment and * therefore cannot be cleared with array operations or memset. */static void EraseWindow(void){    GrafPtr saveWindow;    Rect rect;    int width, height;    GetPort(&saveWindow);    SetPort((WindowPtr) gWindow);    width = RectWidth(&gWindow->port.portRect);    height = RectHeight(&gWindow->port.portRect);    SetRect(&rect, 0, 0, width, height);    InvalRect(&rect);    SetPort(saveWindow);    CopyBits(&((GrafPtr) osWindow)->portBits,             &((GrafPtr) osWindow)->portBits,             &((GrafPtr) osWindow)->portRect,             &((GrafPtr) osWindow)->portRect,             srcBic, NULL);}/* * Function: CreateGraphicsWindow * Usage: CreateGraphicsWindow(); * ------------------------------ * This function creates the graphics window on the screen and * the offscreen memory to back it up. */static void CreateGraphicsWindow(void){    GrafPtr wPort;    WindowPtr cWindow;    double xScale, yScale, scaleFactor;    double xSpace, ySpace;    int gHeight, cHeight;    int left, top;    Rect bounds;    long nBytes;    void *base;    GetWMgrPort(&wPort);    ScreenRes(&xResolution, &yResolution);    left = console_options.left;    top = console_options.top;    xSpace = InchesX(RectWidth(&wPort->portRect) - left) - RightMargin;    ySpace = InchesY(RectHeight(&wPort->portRect) - top) - BottomMargin             - ConsoleHeight - 2 * InchesY(TitleBarPixels);    xScale = yScale = 1.0;    if (windowWidth > xSpace) {        xScale = xSpace / windowWidth;    }    if (windowHeight > ySpace) {        yScale = ySpace / windowHeight;    }    scaleFactor = MinF(xScale, yScale);    gHeight = PixelsY(windowHeight * scaleFactor) + TitleBarPixels;    console_options.top += gHeight + PixelsY(WindowSeparation);    console_options.nrows = ConsoleLines;    console_options.title = "\pConsole Window";    printf("\n");    fflush(stdout);    consoleFile = *stdout;    cHeight = RectHeight(&((GrafPtr) stdout->window)->portRect);    cWindow = (WindowPtr) stdout->window;    SizeWindow(cWindow, PixelsX(DesiredWidth), cHeight, 0);    MoveWindow(cWindow, left, console_options.top, TRUE);    xResolution *= scaleFactor;    yResolution *= scaleFactor;    SetRectFromSize(&bounds, left, top,                    PixelsX(windowWidth), PixelsY(windowHeight));    colorOK = (TestDeviceAttribute(GetMainDevice(), gdDevType) != 0);    if (colorOK) colorOK = CreateColorWindow(&bounds);    if (!colorOK) {        if (!CreateBWWindow(&bounds)) {            Error("InitGraphics: Can't create window");        }    }    EraseWindow();    ShowWindow((WindowPtr) gWindow);}/* * Function: CreateColorWindow * Usage: success = CreateColorWindow(&bounds); * -------------------------------------------- * This function tries to create a color graphics window with * the specified bounds.  If it succeeds, the resulting window * is stored in the global variable gWindow and the corresponding * offscreen bitmap is stored in the pseudowindow osWindow.  The * function returns TRUE on success and FALSE on failure. */static bool CreateColorWindow(Rect *bounds){    CGrafPtr gPort, osPort;    Rect visRect;    int nColors;    long nBytes;    void *base;    gWindow = (WindowPeek) NewCWindow(NULL, bounds,                                      PascalString(windowTitle),                                      FALSE, 0, (WindowPtr) -1, FALSE, 0);    if (gWindow == NULL) return (FALSE);    gPort = (CGrafPtr) gWindow;    nColors = (*(*gPort->portPixMap)->pmTable)->ctSize + 1;    if (nColors < MinColors) {        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    osWindow = (WindowPeek) malloc(sizeof(CGrafPort));    if (osWindow == NULL) {        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    osPort = (CGrafPtr) osWindow;    *osPort = *gPort;    if ((osPort->visRgn = NewRgn()) == NULL) {        free(osWindow);        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    visRect = *bounds;    OffsetRect(&visRect, -bounds->left, -bounds->top);    RectRgn(osPort->visRgn, &visRect);    if ((osPort->portPixMap = NewPixMap()) == NULL) {        free(osWindow);        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    CopyPixMap(gPort->portPixMap, osPort->portPixMap);    nBytes = (long) RectHeight(bounds)               * ((*osPort->portPixMap)->rowBytes & 0x3FFF);    base = calloc(nBytes, 1);    if (base == NULL) {        DisposePixMap(osPort->portPixMap);        free(osWindow);        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    (*osPort->portPixMap)->baseAddr = base;    return (TRUE);}/* * Function: CreateBWWindow * Usage: success = CreateBWWindow(&bounds); * ----------------------------------------- * This function is identical to CreateColorWindow except that * it creates a black-and-white window.  This function is used * if the device does not support color or if there is not * enough memory to create a color bitmap. */static bool CreateBWWindow(Rect *bounds){    GrafPtr gPort, osPort;    Rect visRect;    void *base;    gWindow = (WindowPeek) NewWindow(NULL, bounds,                                     PascalString(windowTitle),                                     FALSE, 0, (WindowPtr) -1, FALSE, 0);    if (gWindow == NULL) return (FALSE);    gPort = (GrafPtr) gWindow;    osWindow = (WindowPeek) malloc(sizeof(GrafPort));    if (osWindow == NULL) {        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    osPort = (GrafPtr) osWindow;    *osPort = *gPort;    if ((osPort->visRgn = NewRgn()) == NULL) {        free(osWindow);        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    visRect = *bounds;    OffsetRect(&visRect, -bounds->left, -bounds->top);    RectRgn(osPort->visRgn, &visRect);    base = calloc((long) RectHeight(bounds) * osPort->portBits.rowBytes, 1);    if (base == NULL) {        free(osWindow);        DisposeWindow((WindowPtr) gWindow);        return (FALSE);    }    osPort->portBits.baseAddr = base;    return (TRUE);}/* * Function: PrepareToDraw * Usage: PrepareToDraw(); * ----------------------- * This function must be called before any rendering operation * to ensure the pen modes and colors are correctly set.  The * port must already be selected when this function is called. */static void PrepareToDraw(void){    bool erase;    RGBColor color;    erase = eraseMode;    if (colorOK) {        color.red = colorTable[penColor].red * 0xFFFFL;        color.green = colorTable[penColor].green * 0xFFFFL;        color.blue = colorTable[penColor].blue * 0xFFFFL;        RGBForeColor(&color);    } else {        if (ShouldBeWhite()) erase = TRUE;    }    PenMode((erase) ? patBic : patCopy);    TextMode((erase) ? srcBic : srcOr);}/* * Function: PrepareToDrawText * Usage: PrepareToDrawText(); * --------------------------- * This function must be called before any text rendering operation. * The port must already be selected when this function is called. */static void PrepareToDrawText(void){    int fnum;    PrepareToDraw();    fnum = GetFontNumber(textFont);    if (fnum == 0) Error("Internal error: illegal font");    TextFont(fnum);    TextSize(pointSize);    TextFace(((textStyle & Bold) ? bold : 0)             | ((textStyle & Italic) ? italic : 0));}/* * Function: DisplayLine * Usage: DisplayLine(x, y, dx, dy); * --------------------------------- * This function displays a line segment from the point (x, y) * to the point (x + dx, y + dy).  Like all of the other graphical * operations, the line is rendered into offscreen memory.  The * actual screen is updated only in response to the update event. */static void DisplayLine(double x, double y, double dx, double dy){    GrafPtr saveWindow;    Rect rect;    int ix0, iy0, ix1, iy1;    ix0 = ScaleX(x);    iy0 = ScaleY(y);    ix1 = ScaleX(x + dx);    iy1 = ScaleY(y + dy);    SetRect(&rect, Min(ix0,ix1), Min(iy0,iy1), Max(ix0,ix1), Max(iy0,iy1));    UpdateRect(&rect);    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDraw();    MoveTo(ix0, iy0);    LineTo(ix1, iy1);    SetPort(saveWindow);}/* * Function: DisplayArc * Usage: DisplayArc(x, y, rx, ry, start, sweep); * --------------------------------------------- * This function displays an elliptical arc segment centered at * the point (x, y).  (Note that the argument signature is different * from that of the client function DrawEllipticalArc.) */static void DisplayArc(double x, double y, double rx, double ry,                       double start, double sweep){    GrafPtr saveWindow;    Rect rect;    int ix0, iy0, ix1, iy1, istart, isweep;    istart = Round(start);    isweep = Round(sweep);    ix0 = ScaleX(x - rx);    iy0 = ScaleY(y + ry);    ix1 = ix0 + PixelsX(2 * rx);    iy1 = iy0 + PixelsY(2 * ry);    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDraw();    SetArcBB(&rect, x, y, rx, ry, start, sweep);    UpdateRect(&rect);    SetRect(&rect, ix0, iy0, ix1+1, iy1+1);    FrameArc(&rect, 90 - istart, -isweep);    SetPort(saveWindow);}/* * Function: RenderArc * Usage: RenderArc(x, y, rx, ry, start, sweep); * --------------------------------------------- * This function is identical to the DisplayArc function except * that the arc is rendered using line segments.  This complication * is necessary on the Macintosh for filled shapes because arcs are * not counted as region boundaries.  As an optimization, a * complete circle or oval is drawn using the DrawOval tool, which * does add a region boundary.  The arc unit is chosen to represent * a pixel width at the specified arc radius. */static void RenderArc(double x, double y, double rx, double ry,                      double start, double sweep){    GrafPtr saveWindow;    double t, mint, maxt, dt;    int ix0, iy0, ix1, iy1;    Rect rect;    GetPort(&saveWindow);    SetPort((WindowPtr) osWindow);    PrepareToDraw();    if (sweep < 0) {        start += sweep;        sweep = -sweep;    }    if (sweep > 360 - Epsilon) {        ix0 = ScaleX(x - rx);        iy0 = ScaleY(y + ry);        ix1 = ix0 + PixelsX(2 * rx);        iy1 = iy0 + PixelsY(2 * ry);        SetRect(&rect, ix0, iy0, ix1+1, iy1+1);

⌨️ 快捷键说明

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