305 lines
12 KiB
HTML
305 lines
12 KiB
HTML
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||
|
<meta name="GENERATOR" content="Mozilla/4.6 [en] (X11; I; Linux 2.2.9-19mdk i586) [Netscape]">
|
||
|
</head>
|
||
|
<body>
|
||
|
|
||
|
<center><font size=+2>MiGS Overview</font>
|
||
|
<br><font size=+2>A Minimalist Graphics Subsystem</font>
|
||
|
<p>
|
||
|
<hr WIDTH="100%"></center>
|
||
|
|
||
|
<h1>
|
||
|
<font size=+0>Introduction</font></h1>
|
||
|
|
||
|
<blockquote>This document details the design and implementation of MiGS,
|
||
|
the minimalist graphics subsystem used by the FreeType 2 demonstration
|
||
|
programs. Its purpose is mainly to help writers of new demo programs, as
|
||
|
well as developers who would like port the subsystem to other platforms.</blockquote>
|
||
|
|
||
|
<hr WIDTH="100%">
|
||
|
<h1>
|
||
|
I - Design goals</h1>
|
||
|
|
||
|
<blockquote>MiGS is a tiny graphics subsystem used to demo text rendering
|
||
|
through the FreeType library. It was mainly written to provide the abilities
|
||
|
to :</blockquote>
|
||
|
|
||
|
<ul>
|
||
|
<ul>
|
||
|
<li>
|
||
|
draw a monochrome glyph bitmap to many kinds of target surfaces (i.e. really
|
||
|
bitmaps/pixmaps)</li>
|
||
|
|
||
|
<li>
|
||
|
draw an anti-aliased glyph bitmap, with any level of grays, to many kinds
|
||
|
of target surfaces</li>
|
||
|
|
||
|
<li>
|
||
|
display a simple window on many systems like X11, OS/2 and Windows</li>
|
||
|
|
||
|
<li>
|
||
|
accept simple events (keypresses and mouse buttons) in this window.</li>
|
||
|
|
||
|
<li>
|
||
|
to be portable and present a unified API on all running systems</li>
|
||
|
</ul>
|
||
|
|
||
|
<p><br>MiGS uses system-specific "drivers" in order to perform display
|
||
|
and event handling. The blitting functions are not device-specific. MiGS
|
||
|
can be built and/or used with no system-specific features, like for example,
|
||
|
to generate simple GIF, PNG, TIFF, etc.. images without ever needing to
|
||
|
display them.</ul>
|
||
|
|
||
|
<h1>
|
||
|
|
||
|
<hr WIDTH="100%"></h1>
|
||
|
|
||
|
<h1>
|
||
|
II - Surfaces, bitmaps and windows</h1>
|
||
|
|
||
|
<blockquote>A surface in MiGS models a drawable region where glyph images
|
||
|
can be rendered, a surface always contains a bitmap descriptor as well
|
||
|
as a few other things that will be described later in this section.
|
||
|
<p>Some surfaces can be displayed, they are then either called <i>windowed
|
||
|
surfaces</i> or <i>screen surfaces</i> depending on the nature of the <i>device</i>
|
||
|
used to display them. Each <i>device</i> is implemented by a very simple
|
||
|
<i>driver</i> in the MiGS code. Here are a few example devices that are
|
||
|
or could be written to display surfaces :
|
||
|
<p>- an X11 device
|
||
|
<br>- a Win 32 GDI device
|
||
|
<br>- an OS/2 Presentation Manager device
|
||
|
<br>- a fullscreen SVGALib device on Linux
|
||
|
<br>- a GGI visual device
|
||
|
<br>- an OS/2 "Dive" device, or the equivalent Win32 "DirectX" device
|
||
|
<p>etc..
|
||
|
<p><b>NOTE: </b>For now, only the X11 device was written and tested.. More
|
||
|
devices should come later
|
||
|
<p>Before explaining how to create a surface, we need to explain how MiGS
|
||
|
manages bitmaps and renders glyph images to them.
|
||
|
<h3>
|
||
|
1. Bitmaps :</h3>
|
||
|
|
||
|
<blockquote>A bitmap in MiGS features the following things :
|
||
|
<ul>
|
||
|
<li>
|
||
|
a <b><i>width</i></b> in pixels</li>
|
||
|
|
||
|
<li>
|
||
|
a <b><i>height</i></b> in pixels</li>
|
||
|
|
||
|
<li>
|
||
|
a <b><i>pixel mode</i></b>, which indicates how the pixels are stored in
|
||
|
the surface's buffer</li>
|
||
|
|
||
|
<li>
|
||
|
a <b><i>pitch</i></b>, whose absolute values is the number of bytes taken
|
||
|
by each surface row</li>
|
||
|
|
||
|
<li>
|
||
|
a <b><i>number</i></b> of valid <b><i>gray</i></b> levels (see below)</li>
|
||
|
|
||
|
<li>
|
||
|
a <b><i>buffer</i></b>, holding the surface's pixels</li>
|
||
|
</ul>
|
||
|
|
||
|
<p><br>MiGS uses the <i>"Y downwards"</i> convention, which means that
|
||
|
<i>increasing
|
||
|
Y</i> coordinates correspond to <i>lower rows</i> of the bitmap. Hence,
|
||
|
the coordinate <i>(0,0)</i> always corresponds to the bitmap's
|
||
|
<i>top-left
|
||
|
pixel</i>.
|
||
|
<p>The bitmap's rows can be stored either <i>"downwards"</i> or <i>"upwards"</i>
|
||
|
in the pixel buffer.
|
||
|
<p>In the first case (<i>downwards</i>), increasing memory addresses in
|
||
|
the pixel buffer correspond to lower rows of the bitmap(e.g. PC video modes),
|
||
|
and the <b><i>pitch</i></b> should be equal to <b><i>the number of bytes
|
||
|
taken by each row</i></b>. The first pixel buffer byte corresponds to the
|
||
|
upper row.
|
||
|
<p>In the second case (<i>upwards</i>), increasing memory addresses in
|
||
|
the pixel buffer correspond to upper rows of the bitmap and the <b><i>pitch</i></b>
|
||
|
should be equal to the <b><i>opposite</i></b> of <i>the number of bytes
|
||
|
taken by each row</i>. The first pixel buffer byte corresponds to the lower
|
||
|
row.
|
||
|
<p>In all cases, the <b><i>pitch</i></b> is the <i>increment to be used
|
||
|
to go from one bitmap row to the one below it</i>.
|
||
|
<p>The supported pixel modes are :
|
||
|
<ul>
|
||
|
<li>
|
||
|
1-bit monochrome bitmaps. With "0" as the background, and "1" as the foreground.</li>
|
||
|
|
||
|
<li>
|
||
|
4-bit color bitmaps, using an arbitrary palette.</li>
|
||
|
|
||
|
<li>
|
||
|
8-bit color bitmaps, using an arbitrary palette.</li>
|
||
|
|
||
|
<li>
|
||
|
8-bit gray bitmaps, using a given N number of gray levels in the range
|
||
|
0..N-1.</li>
|
||
|
|
||
|
<li>
|
||
|
15-bit color bitmaps, also known as RGB555</li>
|
||
|
|
||
|
<li>
|
||
|
16-bit color bitmaps, also known as RGB565</li>
|
||
|
|
||
|
<li>
|
||
|
24-bit color bitmaps, also known as RGB</li>
|
||
|
|
||
|
<li>
|
||
|
32-bit color bitmaps, also known as RGBA (though the A is ignored by MiGS)</li>
|
||
|
</ul>
|
||
|
The bitmap's <b><i>number of gray levels</i></b> is only relevant for <b><i>8-bit
|
||
|
gray bitmaps</i></b>, and indicates the range of gray levels that can be
|
||
|
found in the bitmap. If a bitmap as N gray levels, it is said to be <i>N-grayscales</i>,
|
||
|
and the pixels within it must all have values between 0, considered as
|
||
|
the <i>background</i> color, and N-1, considered as the <i>foreground</i>
|
||
|
color.
|
||
|
<p>N-grayscale bitmaps are crucial for the rendering of anti-aliased text.
|
||
|
<br> </blockquote>
|
||
|
|
||
|
<h3>
|
||
|
2. Glyph images :</h3>
|
||
|
|
||
|
<blockquote>The glyph images that can be drawn on bitmaps through MiGS
|
||
|
are bitmaps themselves, though limited to the following pixel modes :
|
||
|
<p><b>1-bit monochrome glyph bitmaps</b>
|
||
|
<blockquote>These can be drawn on any kind of bitmap. Note that <i>only
|
||
|
the "lit" pixels</i> (i.e. the bits set to 1) are effectively drawn to
|
||
|
the target, as opaque blitting isn't supported (remember, it's a minimalist
|
||
|
library !)</blockquote>
|
||
|
|
||
|
<p><br><b>N-grayscales glyph images </b>(with any value of N >= 2)
|
||
|
<blockquote>These can be drawn to <i>all RGB bitmaps</i> (15, 16, 24 &
|
||
|
32 bits/pixel), as well as any other M-grayscales bitmaps. In the latter
|
||
|
case, the values of N and M <i>need not be equal</i>, as the library is
|
||
|
able to perform automatic conversions <i>on the fly</i>.
|
||
|
<p>For example, it is possible to render a 5-grayscales glyph image into
|
||
|
a 128-grayscales bitmap. Moreover, it is also possible to render a 17-grayscales
|
||
|
glyph image into a 5-grayscales bitmap, even if this will result in <i>a
|
||
|
loss of quality</i>. This feature is crucial in order to experiment easily
|
||
|
with other anti-aliasing algorithms for FreeType
|
||
|
<br> </blockquote>
|
||
|
Note that you can <i>only</i> draw <i>monochrome</i> bitmaps to the following
|
||
|
pixel modes : monochrome, 4-bit color and 8-bit color.</blockquote>
|
||
|
|
||
|
<h3>
|
||
|
3. Windows and Screens:</h3>
|
||
|
|
||
|
<blockquote>In order to debug FreeType, displaying a surface in a window
|
||
|
or in full-screen mode, is required. MiGS thus makes a difference between
|
||
|
<i>simple
|
||
|
surfaces</i>, which only contain a bitmap, <i>windowed surfaces</i>, which
|
||
|
are used to display their content in a window, and <i>screen surfaces</i>,
|
||
|
which are used to display their content in a full-screen mode (SVGAlib,
|
||
|
DirectX, GGI or wathever).
|
||
|
<p>A few important things must be said about non-simple surfaces.
|
||
|
<br>
|
||
|
<ul>
|
||
|
<li>
|
||
|
First, they might contain some system-specific data which is used to manage
|
||
|
the display in a window or on the screen. This must be <i>completely hidden</i>
|
||
|
to MiGS clients. Indeed, rendering to any kind of surface is achieved through
|
||
|
<i>exactly
|
||
|
the same function calls</i>.</li>
|
||
|
</ul>
|
||
|
|
||
|
<ul>
|
||
|
<li>
|
||
|
Second, they may contain a bitmap whose pixel mode doesn't correspond to
|
||
|
the screen's depth used to display it. For example, the surface might contain
|
||
|
an 128-grayscale bitmap, while the screen is in RGB24 mode. Some conversion
|
||
|
must be performed to display the surface. This can either happen in the
|
||
|
system-specific graphics library (e.g. on OS/2, a single Presentation Manager
|
||
|
call is used to blit a N-grayscale image to <i>any</i> kind of window)
|
||
|
or in the system-specific part of MiGS (e.g. the X11 MiGS driver must convert
|
||
|
the surface's bitmap into the appropriate <i>X11 image</i> each time a
|
||
|
repaint is requested). Again this must be completely hidden to MiGS clients</li>
|
||
|
</ul>
|
||
|
Surfaces have also a few fields that are only used when displaying them
|
||
|
in Windows :
|
||
|
<p><b>a title string</b>
|
||
|
<blockquote>This is simply a text string that is displayed on the title
|
||
|
bar of the surface's window. It can also appear at the top or bottom of
|
||
|
full-screen surfaces if the MiGS driver supports it. The title string can
|
||
|
be changed with a call to <tt>grSetTitle</tt>, and is ignored for simple
|
||
|
surfaces.</blockquote>
|
||
|
|
||
|
<p><br><b>a refresh flag</b>
|
||
|
<blockquote>This boolean flag is only used for window surfaces, and some
|
||
|
fullscreen ones (depending on the driver implementation). When set, it
|
||
|
indicates that each glyph image blit must be displayed immediately. By
|
||
|
default, this flag is set to False, which means that demo programs must
|
||
|
call the <tt>grRefreshSurface(surface)</tt> function to display the whole
|
||
|
contents of a surface one it has been updated.
|
||
|
<p>The refresh flag can be set with <tt>grSetSurfaceRefresh(surface,flag)</tt>.
|
||
|
Note that a single surface rectangle can be forced to be displayed with
|
||
|
a call to <tt>grRefreshRectangle(surface,x,y,w,h)</tt> at any time.</blockquote>
|
||
|
</blockquote>
|
||
|
|
||
|
<h3>
|
||
|
4. Devices :</h3>
|
||
|
|
||
|
<blockquote>As said before, each device is in charge of displaying a surface
|
||
|
in a given window or screen. Each device is managed through a very simple
|
||
|
driver, described to MiGS through a very simple "grDevice" structure.
|
||
|
<p>A grDevice contains, among other things, pointers to the functions used
|
||
|
to:
|
||
|
<p>- refresh/display a given rectangle of the surface to the window/screen
|
||
|
<br>- listen events (key presses and mouse) and send them back to client
|
||
|
apps.
|
||
|
<br>- for windowed devices, update the title bar.
|
||
|
<p>As said before, this is a highly minimalist system..
|
||
|
<br> </blockquote>
|
||
|
</blockquote>
|
||
|
|
||
|
<hr WIDTH="100%">
|
||
|
<h1>
|
||
|
III - Important implementation issues :</h1>
|
||
|
|
||
|
<blockquote>
|
||
|
<h3>
|
||
|
1. Display surface negociation :</h3>
|
||
|
|
||
|
<blockquote>A display surface is created with the function grNewScreenSurface
|
||
|
which takes parameters indicating which device should be used, the pixel
|
||
|
dimensions of the requested surface, as well as its pixel mode.
|
||
|
<p>Because of some device-specific limitations, the resulting surface's
|
||
|
properties might not match exactly those requested for the call. Hence,
|
||
|
a developper should <b>always take care </b>of reading a new display surface's
|
||
|
<b>bitmap</b> descriptor in order to get its <i>real</i> dimensions, pixel
|
||
|
mode and eventually number of grays.
|
||
|
<p>The function grNewSurface will create a memory surface with the corresponding
|
||
|
bitmap.
|
||
|
<br>The function grNewBitmapSurface will create a surface from a pre-existing
|
||
|
bitmap. This is useful to draw text on loaded images, for example.
|
||
|
<p>Any surface (display or not) is destroyed with grDoneSurface.</blockquote>
|
||
|
|
||
|
<h3>
|
||
|
</h3>
|
||
|
|
||
|
<h3>
|
||
|
2. Supporting 8-bit grayscale mode :</h3>
|
||
|
|
||
|
<blockquote>It is important, for the debugging of FreeType anti-aliased
|
||
|
renderer(s), that <b><i>_all_ devices should support the 8-bit gray mode</i></b>.
|
||
|
The number of gray levels can be fixed or negociated as required by implementation-specific
|
||
|
issues.
|
||
|
<p>As most existing devices do not provide direct support for such a mode,
|
||
|
each 8-bit surface must thus contain :
|
||
|
<p>- an internal N-grayscale bitmap, used as the target of all glyph drawings
|
||
|
<br>- its own device-specific "image", which matches the display depth.
|
||
|
<p>Each time the device's "refresh_rect" function is called, it should
|
||
|
then :
|
||
|
<br>- convert the grayscales within the bitmap's rectangle into the image's
|
||
|
buffer and format.
|
||
|
<br>- display the corresponding image rectangle.
|
||
|
<p>This scheme is used, for example, by the X11 device.</blockquote>
|
||
|
</blockquote>
|
||
|
|
||
|
</body>
|
||
|
</html>
|