The S3 presentation driver supports two different types of character output. One type is GRECharStringPos, which is implemented in the S3 driver by eddt_CharStringPos, in the EDDNGCHS.C file. The other type supports AVIO (Advanced Video Input/Output) text, which is used in OS/2 and DOS window sessions.

The eddt_CharStringPos function uses two strategies for displaying text to the screen. For most strings, it will cache glyphs from the font. While cached, it will draw text by expanding the monochrome bit maps in the font cache to the display. There are, however, some cases where it cannot do this. One case is when the character to be cached is higher than the height of the font cache. Very large fonts will overflow the font cache, as the font cache is typically 127 scan lines tall in the S3 driver. Another reason it may be impossible to cache the glyphs is that the driver may be in 24-bit-per-pel mode, and the requested text is not some shade of gray. A third possibility is that the requested raster operation may be one that has problems on certain S3 chips. A fourth possibility is that only a single character in a font appears, making it undesirable to put it in the font cache. (Doing so might evict a heavily used font so that a single character may be cached.) In any of these cases, eddt_CharStringPos draws characters using BitBlt.

The following is an example of pseudocode for eddt_CharStringPos:

eddt_CharStringPos:
pFocaFont = Current Font
Check that request is valid
if simulation is required
    call back to engine to perform simulation

if display is disabled
    remove COM_DRAW bit from command flags
    if correlation required
        get correlation rectangles

if opaque rectangle is present
    if coordinates must be transformed
        set up opaque rect coordinates for transformation
    else
        get opaque rectangle coordinates

Get starting coordinates for the string

Transform any coordinates that need to be transformed to
device space

if increment vector is present
    convert increment vectors to device space

if current font has only a single character
    BltOneChar = TRUE
    Set up character spacing
    set PerCharDefs to a pointer to the character
    get character width and height
    get character A, B, C space
    if increment vector is present
        add in increment vector
    else
        add in character width
else
    BltOneChar = FALSE
    if character is too tall to fit in the cache
        CharTooBig = TRUE

    if font cache is disabled
        CharTooBig = TRUE

    if requested raster operation is defective on the S3 chip
        CharTooBig = TRUE

    if 24 bits per pixel
        get foreground and background colors
        if NOTGREY(foreground) and NOTGREY(background)
            CharTooBig = TRUE

    Compute starting position for the string

    if cursor is software
        Disable cursor

    if CharTooBig == FALSE
        if font is not in the font cache
            eddt_LocateCachedFont()    //Get a font cache entry

        if eddh_update_cache() == FALSE    //unable to fit font in cache
            eddt_LocateCachedFont()    //Get a font cache entry
            if eddh_update_cache() == FALSE
                bail out of string operation, the font is too big

    reenable cursor
    do one last bit of boundary setup (eddt_GetTextBox)

if there is an increment vector
    add in increment to x position

if BltOneChar == TRUE
    adjust starting position to be compatible with BitBlt
else
    adjust starting position to be compatible with string blt

if opaqueing rectangle required
    build opaque rectangle

if clipping rectangle
    clip bounding rectangle against clip rectangle
    if CharTooBig == FALSE and string completely clipped
        goto UPDATE_POS

    clip opaque rect against clipping rectangle

    if opaque rect entirely clipped
        disable COM_DRAW bit in command flags
else
    handle multiple clip rects if necessary

if we need to accumulate bounds
     accumulate bounds

if we need to perform correlation
    perform correlation

if COM_DRAW is not set in command flags
    goto CHARSTRPOS_OK_EXIT

if destination is the display
    SetDrawModeHard
else
    SetDrawModeSoft

if software cursor
    exclude cursor

setup foreground and background colors

if opaque rectangle must be drawn
    set pixelop
    set mix, blt source, no color compare
    TransferShadowRegisters()
    //draw the opaque rect via pattern blt
    eddb_DrawThroughClips(index_PatDestBlt)

if number of characters to draw is 0
    goto CHARSTRPOS_OK_EXIT

//special case #1 -- we have a font with a single character
if BltOneChar == TRUE
    calculate size of character in bytes
    copy character into the Phunk, putting it in row major order
    Create a bit map header for the character
    set up pixelop, mix, source, colors etc.
    TransferShadowRegisters()
    Setup AIxfer for a BitBlt
    while count of characters > 0
        fix up the character for BitBlt
        eddb_DrawThroughClips(index_SrcDestBlt)
        update position of next character
        decrement count of characters
    goto UPDATE_POS

//special case #2 -- uncacheable font
if CharTooBig == TRUE
    set up colors, mixes, source, etc.
    TransferShadowRegisters()
    while count of characters > 0
        get character width and height
        set pCharDefn to point to the character bit map
        get A, B, and C space
        copy the character into the Phunk, putting it in row major order
        setup a bit map header for the character bit map
        setup AIxfer for a BitBlt
        fixup source and destination values so they are non-negative
        eddb_DrawThroughClips(index_SrcDestBlt)
        advance to next character position
        decrement count of characters
     goto UPDATE_POS

//finally we get to draw text through the code in eddhgchs.asm
set up pointer to the font in AIxfer
store a pointer to the code points and position of first char in AIxfer
set up mixes, source, colors
TransferShadowRegisters()

if position vector present
    //draw them one at a time -- we have a position vector
    set number of characters in AIxfer to 1
    while count of characters > 0
        store increment from vector in AIxfer.bCharWidth
        eddb_DrawThroughClips(index_DrawText)
        update position of next character from position vector
        point to next character
        decrement count of characters
else
    Set count of character in AIxfer to number of characters in string
    eddb_DrawThroughClips(index_DrawText)

UPDATE_POS:
update position if required

if destination cached
    evict cached bit map

CHARSTRPOS_OK_EXIT:
reenable cursor

In eddt_CharStringPos and in the character-caching code, notice the following loop:

for (i = 0; i < CharHeight; i++)
{
    source_index = i;
    for (j = CharBytesPerRow; j--; )
    {
        *pCharBuffer++ = pCharDefn[source_index];
        source_index += CharHeight;
    }
}

This loop is a difficult copy operation because presentation stores the bit maps for glyphs in column major order, rather than in row-major order. That is, all of the bytes that make up the first column of a character are stored one after another, followed by all of the bytes of the second column, and so forth. The bits in each byte of monochrome data are in Motorola** order; that is, bit 7 is the left-most bit, and bit 0 is the right-most bit. Also, after the inner loop rearranges the glyph, the byte ordering is in Motorola order. For other devices, it is possible that either or both the bit and byte ordering may have to be altered.

The eddt_CharStringPos function caches characters in off-screen VRAM. The first portion of this involves determining if the font has already been cached. The eddt_LocateCachedFont() data field, in EDDNCACH.C, searches the array of FontCacheInfo structures. If it finds a matching font, it returns. If not, it evicts a font from the cache, and sets the usCachedFontIndex field in the passed-in parameter in the FONTDETAILS structure. The FONTDETAILS structure is defined in the EDDTYPET.H file, and it stores a pointer to the font and a cache slot, among other things. The S3 driver supports the caching of up to 8 fonts; therefore, the array of pointers to FontCacheInfo structures (pFontCacheInfo) consists of 8 entries.

When an entry has been found for the font, it is necessary to actually cache the characters in the string. This caching is handled by eddh_update_cache, which is in the EDDHGCHS.ASM file. The eddh_update_cache loops through the string, and for each character that is not already cached, it calls eddt_CacheCharacter (in EDDNCACH.C). The code in eddt_CacheCharacter is similar to the code in eddt_CharStringPos that uses BitBlt to display a single character. First, it attempts to find a position in the cache for the character. The 8514/A and the S3 driver stores a single font in a single plane of VRAM. In 16-bit-per-pel modes, the S3 driver allows a font to wrap to another plane. Because the 8514/A interacts with bit maps as rectangles, eddt_CacheCharacter calculates an X-Y coordinate for the character in the font cache, and calls Cache8514Char (in EDDHGCHS.ASM) to copy the glyph into off-screen memory.

In the cases where it is not using BitBlt, eddt_CharStringPos uses either eddh_DrawText (if the destination is the display), or eddf_DrawText (if the destination is not the display). The eddh_DrawText function loops through an array of clipping rectangles, drawing the string (or portion thereof) into each clipping rectangle. The complexity of eddh_DrawText results from the fact that it does not use the S3 chip hardware-scissoring capabilities to clip the text. Instead, if part of a character is clipped, it calculates offsets into the character, and into the destination so that only the portions of the character that are inside the clipping rectangle are actually drawn. When all of that has been set up, the character is BitBlted by way of a hardware monochrome expansion blt from the character cache to the display.


[Back: eddb_BltThroughClips and eddb_DrawThroughClips (EDDNBBLT.C)]
[Next: Advanced Video Input/Output (AVIO) Text]