📄 graphics.c
字号:
}double TextStringWidth(string text){ RECT r; InitCheck(); SetTextBB(&r, cx, cy, text); return (InchesX(RectWidth(&r)));}void SetFont(string font){ InitCheck(); DisplayFont(font, pointSize, textStyle);}string GetFont(void){ InitCheck(); return (CopyString(textFont));}void SetPointSize(int size){ InitCheck(); DisplayFont(textFont, size, textStyle);}int GetPointSize(void){ InitCheck(); return (pointSize);}void SetStyle(int style){ InitCheck(); DisplayFont(textFont, pointSize, style);}int GetStyle(void){ InitCheck(); return (textStyle);}double GetFontAscent(void){ InitCheck(); return (InchesY(fontTable[currentFont].ascent));}double GetFontDescent(void){ InitCheck(); return (InchesY(fontTable[currentFont].descent));}double GetFontHeight(void){ InitCheck(); return (InchesY(fontTable[currentFont].height));}/* Section 5 -- Mouse support */double GetMouseX(void){ InitCheck(); return (InchesX(mouseX));}double GetMouseY(void){ InitCheck(); return (windowHeight - InchesY(mouseY));}bool MouseButtonIsDown(void){ InitCheck(); return (mouseButton);}void WaitForMouseDown(void){ MSG msg; UpdateDisplay(); while (!mouseButton) { if (GetMessage(&msg, graphicsWindow, 0, 0) == 0) exit(0); DispatchMessage(&msg); }}void WaitForMouseUp(void){ MSG msg; UpdateDisplay(); while (mouseButton) { if (GetMessage(&msg, graphicsWindow, 0, 0) == 0) exit(0); DispatchMessage(&msg); }}/* Section 6 -- Color support */bool HasColor(void){ InitCheck(); return (GetDeviceCaps(gdc, NUMCOLORS) >= MinColors);}void SetPenColor(string color){ int cindex; InitCheck(); cindex = FindColorName(color); if (cindex == -1) Error("Undefined color: %s", color); penColor = cindex;}string GetPenColor(void){ InitCheck(); return (CopyString(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) { SetWindowText(graphicsWindow, windowTitle); }}string GetWindowTitle(void){ return (CopyString(windowTitle));}void UpdateDisplay(void){ InitCheck(); DoUpdate();}void Pause(double seconds){ double finish; UpdateDisplay(); finish = (double) clock() / CLK_TCK + seconds; while (((double) clock() / CLK_TCK) < finish);}void ExitGraphics(void){ pauseOnExit = 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; DisplayFont(textFont, pointSize, textStyle); stateStack = sb->link; FreeBlock(sb);}double GetFullScreenWidth(void){ HWND desktop; RECT bounds; desktop = GetDesktopWindow(); GetWindowRect(desktop, &bounds); return ((double) RectWidth(&bounds) / GetXResolution());}double GetFullScreenHeight(void){ HWND desktop; RECT bounds; desktop = GetDesktopWindow(); GetWindowRect(desktop, &bounds); return ((double) RectHeight(&bounds) / GetYResolution());}void SetWindowSize(double width, double height){ if (initialized) return; windowWidth = width; windowHeight = height;}double GetXResolution(void){ HWND desktop; HDC dc; int xdpi; if (initialized) return (xResolution); desktop = GetDesktopWindow(); dc = GetDC(desktop); xdpi = GetDeviceCaps(dc, LOGPIXELSX); ReleaseDC(desktop, dc); return (xdpi);}double GetYResolution(void){ HWND desktop; HDC dc; int ydpi; if (initialized) return (yResolution); desktop = GetDesktopWindow(); dc = GetDC(desktop); ydpi = GetDeviceCaps(dc, LOGPIXELSY); ReleaseDC(desktop, dc); return (ydpi);}/* 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. Because the erase mode and font * information are also maintained in the display state, * InitGraphicsState must call functions to ensure that these * values are initialized there as well. */static void InitGraphicsState(void){ cx = cy = 0; eraseMode = FALSE; textFont = "Default"; pointSize = DefaultSize; textStyle = Normal; stateStack = NULL; regionState = NoRegion; DisplayFont(textFont, pointSize, textStyle);}/* * Function: InitDisplay * Usage: InitDisplay(); * --------------------- * This function does everything necessary to initialize the display. * In this implementation, the graphics window is created as an * overlapping child of the console window, which has been created * by EasyWin. As a child of the console, the window automatically * gets events whenever the console window is waiting for events, * simplifying the logic of the implementation considerably. Most * of the InitDisplay implementation is concerned with calculating * the new tiling geometry, after which the function creates the * new window and an offscreen bitmap to use as a target for any * rendering. When the window gets a Paint event in the event * procedure GraphicsEventProc, all it has to do is copy the * bits from the offscreen bitmap onto the screen. */static void InitDisplay(void){ RECT bounds, consoleRect, graphicsRect; double screenHeight, screenWidth, xSpace, ySpace; double xScale, yScale, scaleFactor; DWORD style; int top, dx, dy, cWidth; clrscr(); atexit(DisplayExit); RegisterWindowClass(); consoleWindow = FindConsoleWindow(); initialized = FALSE; xResolution = GetXResolution(); yResolution = GetYResolution(); initialized = TRUE; screenWidth = GetFullScreenWidth(); screenHeight = GetFullScreenHeight(); xSpace = screenWidth - InchesX(LeftMargin + RightMargin); ySpace = screenHeight - InchesX(TopMargin + BottomMargin) - InchesX(ConsoleHeight + WindowSep); xScale = yScale = 1.0; if (windowWidth > xSpace) xScale = xSpace / windowWidth; if (windowHeight > ySpace) yScale = ySpace / windowHeight; scaleFactor = (xScale < yScale) ? xScale : yScale; if (scaleFactor > MinConsoleScale) { cWidth = PixelsX(DesiredWidth * scaleFactor); } else { cWidth = PixelsX(DesiredWidth * MinConsoleScale); } xResolution *= scaleFactor; yResolution *= scaleFactor; SetRectFromSize(&graphicsRect, LeftMargin, TopMargin, PixelsX(windowWidth), PixelsY(windowHeight)); style = WS_OVERLAPPEDWINDOW & ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); graphicsWindow = CreateWindow(GWClassName, windowTitle, style, graphicsRect.left, graphicsRect.top, RectWidth(&graphicsRect), RectHeight(&graphicsRect), consoleWindow, (HMENU) NULL, (HINSTANCE) NULL, (LPSTR) NULL); if (graphicsWindow == NULL) { printf("InitGraphics: CreateGraphicsWindow failed.\n"); } GetClientRect(graphicsWindow, &bounds); dx = RectWidth(&graphicsRect) - RectWidth(&bounds); dy = RectHeight(&graphicsRect) - RectHeight(&bounds); SetWindowPos(graphicsWindow, HWND_TOP, graphicsRect.left, graphicsRect.top, RectWidth(&graphicsRect) + dx, RectHeight(&graphicsRect) + dy, 0); gdc = GetDC(graphicsWindow); GetClientRect(graphicsWindow, &bounds); pixelWidth = RectWidth(&bounds); pixelHeight = RectHeight(&bounds); ShowWindow(graphicsWindow, SW_SHOW); UpdateWindow(graphicsWindow); osdc = CreateCompatibleDC(gdc); if (osdc == NULL) { Error("Internal error: Can't create offscreen device"); } osBits = CreateCompatibleBitmap(gdc, pixelWidth, pixelHeight); if (osBits == NULL) { Error("Internal error: Can't create offscreen bitmap"); } (void) SelectObject(osdc, osBits); top = TopMargin + WindowSep + PixelsY(windowHeight) + dy; SetRectFromSize(&consoleRect, LeftMargin, top, cWidth + dx, ConsoleHeight); SetWindowText(consoleWindow, "Console Window"); SetWindowPos(consoleWindow, HWND_TOP, consoleRect.left, consoleRect.top, RectWidth(&consoleRect), RectHeight(&consoleRect), 0); InitDrawingTools();}/* * Function: InitDrawingTools * Usage: InitDrawingTools(); * -------------------------- * This function initializes all of the standard objects used for * drawing except for fonts, which are initialized dynamically by * the DisplayFont procedure. This function creates the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -