📄 graphic.c
字号:
if (skey == -1) return (DefWindowProc (handle, msg, wparam, lparam)); strcpy (winkey, ykey[skey]); wantakey = FALSE; SetEvent (gotkey); return 0; } default: return (DefWindowProc (handle, msg, wparam, lparam)); }}static DWORDwinthread (LPWORD par){ /* procedure for windows-thread */ MSG msg; int w, h; RECT cr; /* client area rectangle */ winx = winy = 30; if (!geometry) geometry = getreg ("geometry"); if (geometry) if (sscanf (geometry, "%ix%i+%i+%i", &w, &h, &winx, &winy) != 4 && sscanf (geometry, "+%i+%i", &winx, &winy) != 2 && sscanf (geometry, "%i+%i", &winx, &winy) != 2) winx = winy = 30; /* get window-size from client-area size */ cr.left = winx; cr.right = winx + winwidth; cr.top = winy; cr.bottom = winy + winheight; AdjustWindowRect (&cr, WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE); /* create my window */ window = CreateWindow (my_class, NULL, /* my style */ WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, /* window style */ winx, /* initial x-position */ winy, /* initial y-position */ cr.right - cr.left, /* initial x-size */ cr.bottom - cr.top, /* initial y-size */ NULL, /* parent window */ NULL, /* menu handle */ this_instance, /* my instance */ (LPVOID) NULL); /* dont know why */ /* show my window */ sprintf (string, "%s - Grafic Window", progname); SetWindowText (window, string); ShowWindow (this_instance, SW_SHOW); UpdateWindow (this_instance); SetForegroundWindow (window); winopened = TRUE; /* get colours */ backbrush = CreateSolidBrush (backpixel); backpen = CreatePen (PS_SOLID, 0, backpixel); forebrush = CreateSolidBrush (forepixel); forepen = CreatePen (PS_SOLID, 0, forepixel); /* create bitmap device context */ devcon = GetDC (window); bitcon = CreateCompatibleDC (devcon); cr.left = cr.top = 0; cr.right = winwidth; cr.bottom = winheight; backbit = CreateCompatibleBitmap (devcon, cr.right - cr.left, cr.bottom - cr.top); SelectObject (bitcon, backbit); SelectClipRgn (bitcon, NULL); IntersectClipRect (bitcon, 0, 0, winwidth, winheight); FillRect (bitcon, &cr, backbrush); SelectObject (bitcon, forebrush); SelectObject (bitcon, forepen); ReleaseDC (window, devcon); /* get and dispatch messages */ while (GetMessage ((LPMSG) & msg, NULL, 0, 0)) { TranslateMessage ((LPMSG) & msg); DispatchMessage ((LPMSG) & msg); } /* delete all those objects */ DestroyWindow (window); DeleteObject (backbit); DeleteObject (backpen); DeleteObject (backbrush); DeleteDC (devcon); DeleteDC (bitcon); ExitThread (0); return 0;}static voidstartdraw (int clear){ /* prepare for drawing */ RECT interior; WaitForSingleObject (drawmutex, INFINITE); devcon = GetDC (window); if (clear) { saveddevpen = SelectObject (devcon, backpen); savedbitpen = SelectObject (bitcon, backpen); } else { saveddevpen = SelectObject (devcon, forepen); savedbitpen = SelectObject (bitcon, forepen); } if (clear) { saveddevbrush = SelectObject (devcon, backbrush); savedbitbrush = SelectObject (bitcon, backbrush); } else { saveddevbrush = SelectObject (devcon, forebrush); savedbitbrush = SelectObject (bitcon, forebrush); } GetClientRect (window, &interior); SelectClipRgn (devcon, NULL); IntersectClipRect (devcon, interior.left, interior.top, interior.right, interior.bottom); if (printer) { if (clear) { if (!(savedprnpen = SelectObject (printer, revprinterpen))) error (ERROR, "could not select background printer pen"); } else { if (!(savedprnpen = SelectObject (printer, printerpen))) error (ERROR, "could not select foreground printer pen"); } return; }}static voidenddraw (int clear){ /* release drawing resources */ SelectObject (devcon, saveddevpen); SelectObject (bitcon, savedbitpen); SelectObject (devcon, saveddevbrush); SelectObject (bitcon, savedbitbrush); SelectObject (printer, savedprnpen); ReleaseDC (window, devcon); ReleaseMutex (drawmutex);} char *getreg (char *name){ /* get defaults from Registry */ char *keyname = "SOFTWARE\\yabasic"; HKEY key; char reg[80]; DWORD n; RegOpenKeyEx (HKEY_LOCAL_MACHINE, keyname, 0, KEY_ALL_ACCESS, &key); n = 80; reg[0] = '\0'; RegQueryValueEx (key, name, NULL, NULL, reg, &n); if (reg[0] == '\0') return NULL; return my_strdup (reg);}#endifstatic intgrafinit (void){ /* initialize grafics (either X or Windows) */#ifdef UNIX static int screen; /* Number of Screen on Display */ static XColor asked, got; /* color is complex ... */ static XGCValues xgcvalues; /* Values for Graphics Context */ static unsigned int w, h; /* width and height of window */ int rbits_count, gbits_count, bbits_count; /* number of bits for r,g and b */ XColor exact_match, best_match; /* exact and best matches for required color */ int height; int fontid;#else /* */ int r, g, b;#endif#ifdef UNIX /* get display */ display = XOpenDisplay (displayname); if (display == NULL) { sprintf (string, "could not open display: %s", my_strerror (errno)); error (ERROR, string); return FALSE; } /* get screen */ screen = DefaultScreen (display); root = RootWindow (display, screen); /* find out, which depth is available */ if (!XMatchVisualInfo (display, DefaultScreen (display), 24, TrueColor, &visualinfo) && !XMatchVisualInfo (display, DefaultScreen (display), 32, TrueColor, &visualinfo) && !XMatchVisualInfo (display, DefaultScreen (display), 16, TrueColor, &visualinfo) && !XMatchVisualInfo (display, DefaultScreen (display), 12, TrueColor, &visualinfo) && !XMatchVisualInfo (display, DefaultScreen (display), 8, TrueColor, &visualinfo)) { error (ERROR, "Could not get any TrueColor visual"); return; } /* convert color masks in more convenient values */ for (rbits_shift = 0; (visualinfo.red_mask & 1 << rbits_shift) == 0; rbits_shift++); rbits_max = visualinfo.red_mask >> rbits_shift; for (rbits_count = 0; rbits_max & (1 << rbits_count); rbits_count++); for (gbits_shift = 0; (visualinfo.green_mask & 1 << gbits_shift) == 0; gbits_shift++); gbits_max = visualinfo.green_mask >> gbits_shift; for (gbits_count = 0; gbits_max & (1 << gbits_count); gbits_count++); for (bbits_shift = 0; (visualinfo.blue_mask & 1 << bbits_shift) == 0; bbits_shift++); bbits_max = visualinfo.blue_mask >> bbits_shift; for (bbits_count = 0; bbits_max & (1 << bbits_count); bbits_count++); sprintf (string, "Creating a %d bit True Color map", visualinfo.depth); error (NOTE, string); sprintf (string, "with %d, %d and %d bits for red, green and blue respectively", rbits_count, gbits_count, bbits_count); error (NOTE, string); /* create the colormap */ colormap = XCreateColormap (display, DefaultRootWindow (display), visualinfo.visual, AllocNone); /* now, that we have the colormap, we try to get the colors requested for fore- and background */ if (!foreground) foreground = XGetDefault (display, "yabasic", "foreground"); if (!foreground) foreground = "black"; if (!XLookupColor (display, colormap, foreground, &exact_match, &best_match)) { sprintf (string, "Could not find foreground color '%s'\n", background); error (ERROR, string); return; } forepixel = rgb_to_pixel (best_match.red >> 8, best_match.green >> 8, best_match.blue >> 8); if (!background) background = XGetDefault (display, "yabasic", "background"); if (!background) background = "white"; if (!XLookupColor (display, colormap, background, &exact_match, &best_match)) { sprintf (string, "Could not find background color '%s'\n", background); error (ERROR, string); return; } backpixel = rgb_to_pixel (best_match.red >> 8, best_match.green >> 8, best_match.blue >> 8); /* get size hints */ if (geometry == NULL) geometry = XGetDefault (display, "yabasic", "geometry"); XParseGeometry (geometry, &winx, &winy, &w, &h); sizehints.x = winx; sizehints.y = winy; sizehints.flags = USPosition; /* create graphics context, accept defaults ... */ xgcvalues.foreground = forepixel; xgcvalues.background = backpixel; gc = XCreateGC (display, root, GCForeground | GCBackground, &xgcvalues); /* create graphics context for reverse drawing */ xgcvalues.foreground = backpixel; xgcvalues.background = forepixel; rgc = XCreateGC (display, root, GCForeground | GCBackground, &xgcvalues); /* get font */ if (!font) font = XGetDefault (display, "yabasic", "font"); if (!font) font = "6x10"; if (!change_font (font)) return FALSE;#elif WINDOWS /* choose font */ if (!font) font = getreg ("font"); if (!font) font = "swiss13"; if (!change_font (font)) return FALSE; /* get colours */ if (!foreground) foreground = getreg ("foreground"); if (!foreground) foreground = "0,0,0"; if (sscanf (foreground, "%d,%d,%d", &r, &g, &b) != 3 || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { sprintf (string, "command line option -foreground must be three numbers between 0 and 255, seperated by commas (not '%s')", foreground); error (ERROR, string); return FALSE; } forepixel = RGB (r, g, b); if (!background) background = getreg ("background"); if (!background) background = "255,255,255"; if (sscanf (background, "%d,%d,%d", &r, &g, &b) != 3 || r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { sprintf (string, "command line option -background must be three numbers between 0 and 255, seperated by commas (not '%s')", background); error (ERROR, string); return FALSE; } backpixel = RGB (r, g, b);#endif return TRUE;}static intchange_font (char *name){ /* change font */#ifdef WINDOWS int n; int f; /* int-value of font */ char *family; /* font family */#else static XGCValues xgcvalues; /* Values for Graphics Context */#endif#ifdef UNIX if (font) { if (!myfont || strcmp (font, name)) { if (myfont) XUnloadFont (display, myfont->fid); my_free (font); } else { return TRUE; } } font = my_strdup (name); myfont = XLoadQueryFont (display, font); if (!myfont) { sprintf (string, "could not load font '%s', trying 'fixed' instead", font); error (WARNING, string); myfont = XLoadQueryFont (display, "fixed"); if (!myfont) { error (ERROR, "could not get it"); return FALSE; } } fontheight = myfont->ascent; xgcvalues.font = myfont->fid; if (!XChangeGC (display, gc, GCFont, &xgcvalues)) { sprintf (string, "Could not change font to '%s'", font); error (ERROR, string); return FALSE; } firsttext = TRUE;#else if (font) { if (strcmp (font, name)) { DeleteObject (myfont); my_free (font); } else { return TRUE; } } font = my_strdup (name); f = FF_SWISS; fontheight = 13; family = my_strdup (font); for (n = 0; *(family + n) != '\0' && !isdigit (*(family + n)); n++) *(family + n) = tolower ((int) *(family + n)); if (isdigit (*(family + n))) sscanf (family + n, "%d", &fontheight); *(family + n) = '\0'; if (!strcmp ("decorative", family)) f = FF_DECORATIVE; else if (!strcmp ("dontcare", family)) f = FF_DONTCARE; else if (!strcmp ("modern", family)) f = FF_MODERN; else if (!strcmp ("roman", family)) f = FF_ROMAN; else if (!strcmp ("script", family)) f = FF_SCRIPT; else if (!strcmp ("swiss", family)) f = FF_SWISS; else { sprintf (string, "Don't know font '%s' using 'swiss' instead", font); error (WARNING, string); f = FF_SWISS; } logfont.lfHeight = -fontheight; logfont.lfWidth = 0; logfont.lfEscapement = 0; logfont.lfOrientation = 0; logfont.lfWeight = FW_DONTCARE; logfont.lfItalic = FALSE; logfont.lfUnderline = FALSE; logfont.lfStrikeOut = FALSE; logfont.lfCharSet = DEFAULT_CHARSET; logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; logfont.lfQuality = DEFAULT_QUALITY; logfont.lfPitchAndFamily = DEFAULT_PITCH | f; logfont.lfFaceName[0] = '\0'; myfont = CreateFontIndirect (&logfont); if (myfont == NULL) { sprintf (string, "Could not create font '%s' for screen", font); error (ERROR, string); return FALSE; } my_free (family); if (printer) { /* delete and create printerfont */ if (printerfont) DeleteObject (printerfont); logfont.lfHeight = (long) (-fontheight * prnscale); printerfont = CreateFontIndirect (&logfont); if (printerfont == NULL) { sprintf (string, "Could not create font for printer"); error (ERROR, string); return FALSE; } if (!SelectObject (printer, printerfont)) error (ERROR, "could not select printerfont"); }#endif return TRUE;}#ifdef UNIXvoidcalc_psscale (){ /* calculate scale-factor for postscript */ if ((float) winwidth / winheight > (float) 18 / 25) psscale = 18 * 0.39 * 72 / winwidth; else psscale = 25 * 0.39 * 72 / winheight;}#endifvoidputindrawmode (int mode){ /* store drawmode in previous command */ if (mode) lastcmd->tag = mode; else lastcmd->tag = drawmode; drawmode = 0;}voiddot (struct command *cmd){ /* draw a dot */ double x, y; int clear; y = pop (stNUMBER)->value; x = pop (stNUMBER)->value; transform (&x, &y); clear = cmd->tag & dmCLEAR; if (!winopened) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -