Thursday, November 29, 2007

Graphics mode

Note: The material in this section and the next describes both features that exist and features that are planned for the future. Consult the change log for more info about the support provided in specific code versions.

In true Turbo C, graphics-mode screens (as opposed to text-mode screens) are handled by something called the Borland Graphics Interface, or BGI for short. The BGI is an API containing 80+ functions. Note that the graphics functions provided with the TurboC library are somewhat less portable than the remainder of the library, in that the X-window system is required. If you need graphics functions that can operate without X, I'd suggest reading the next section.

Some of the more important points of departure from true Turbo C are these:

  • External files. True Turbo C relies on the existence of certain plug-in files, specifically the BGI "drivers" (such as EGAVGA.BGI, HERC.BGI, etc.) and the fonts (such as TRIP.CHR, SANS.CHR, etc.). The TurboC library has no such dependence, though it may eventually be possible to load new fonts at runtime. Functions related to manipulation of these files are provided, so that you don't have to take the effort of writing them out of your code, but often they are empty stubs.
  • Missing functions. Implementation of the floodfill function is not presently planned.
  • Screen hiding. Since true Turbo C ran under MS-DOS, a non-windowed non-graphical environment, the way it had to operate was to take over the entire display screen, and to place the hardware graphics controller itself either in "text mode" or in "graphics mode". In other words, if the graphics controller was in text mode then only textual functions (like those in stdio.h or conio.h) could be used, whereas in graphics mode only graphical functions (graphic.h) could be used. Material written to the screen in text mode disappeared when graphics mode was started, and vice-versa. With the TurboC library, because a windowed environment is used, both text-mode windows and graphics-mode windows can appear simultaneously. In other words, when graphics mode is started, a new graphics-mode window is created, but no effort is made to hide the old text-mode window.
  • Palettes. Since true Turbo C dealt with actual modes of the hardware graphics controller, palettes were built into the graphics controller itself, and changes to palettes (for example, reassignment of a palette color, like the background color) were instantly reflected on-screen. With the TurboC library, changes to the paletted (and specifically, to the background color) are reflected only in future screen-writes, and don't affect anything already written to the screen.
  • Text. The bitmapped font is supported. For various reasons, sadly -- having spent a considerable amount of work on it -- I find that it's not convenient to support Borland's "stroked font" (CHR) format. (These reasons include the following: Borland's license does not allow using the Borland-supplied fonts with the TurboC library; nobody has made any free CHR fonts available on the Internet; and, while there are TrueType-to-CHR programs available, they cost more than I'm willing to pay -- i.e., more than zero.) Therefore, the functionality otherwise normally provided by the stroked fonts will eventually be supplied indirectly by means of *nix system fonts. Currently, this has not yet been implemented. Or, you may draw text directly using XlibTcUnicodeMappingsXlib. functions, as described a few lines below. You may also find the array useful when using
  • The getimage and putimage functions . This is described in detail above. Briefly, these functions are used to fetch a rectangular area of the display into an image buffer, or to write the image back to the screen. The formats of the image buffers were undocumented by Borland, but actually corresponded to the memory maps used by the specific graphics controllers and graphics modes. These formats are not duplicated by the TurboC library.
  • Flexibility. You don't need to confine yourself to the BGI functions. You can also use X-window library functions. For example, *nix system fonts -- which BGI obviously doesn't support -- can be used in a TurboC-ported program via Xlib functions like XLoadFont , XDrawString, etc. All you have to know -- other than basic X operations -- is that the TurboC library exposes the following X objects for your use:
    • Display *TcDisplay; // The X-window "display".
      Window TcWindow; // The X-window "window".
      gint TcScreen; // The X-window "screen".
      GC TcGc; // The X-window "graphics context".
    It's necessary to modify the graphics context (TcGc) for any serious drawing. If you don't restore it to its original settings, the TurboC library will become seriously confused. Therefore, it's best to copy followed by the graphics context (with X-window function XCreateGCXCopyGC), and work only with your copy of the graphics context rather than with the original. Also, to avoid threading conflicts, always wrap your X operations as follows:
      XLockDisplay (TcDisplay);
      // ... your X code goes here ...
      // For Example, draw a text string at x=10, y=20:
      XDrawString (TcDisplay, TcScreen, TcGc,
      10, 20, "I am text", 9);
      XSync (TcDisplay);
      XUnlockDisplay (TcDisplay);

No comments: