PreviousIBM PC Character Set IBM PC Display AttributesNext

Chapter 9: Generic Line Drawing

The generic line-drawing system enables you to write source programs that run unmodified in any supported environment and produce the best possible representation of graphic characters available in that environment.

This chapter tells you about the strategy you can use to achieve this, the services provided by the run-time system, and the data items and procedures you need to write into your program.

The descriptions of the available routines are at the end of the chapter.

9.1 Overview

There are 256 possible generic line-drawing characters, each represented by a code in the range 0 through 255. These are called generic codes.

Generic codes are a logical description of line-drawing characters. See the section Finding the Character You Want for an explanation of how to find the code for any character.

The strategy you use to take advantage of generic line drawing works as follows:

  1. As part of initialization, your program asks the run-time system for the environment-specific codes of any characters that it needs. These are called environment codes. You can request:

    The environment codes the run-time system returns are the best representation of the generic characters available in the current environment.

  2. You can store these environment codes as either:

  3. Depending on the way you chose to store the environment codes, you hard-code a data item name or generic code into your program wherever graphic characters are needed.

    This is preferable to hard-coding an environment code, which makes your program specific to one environment.

  4. The reference is used to find the environment code (determined during initialization) then sent to the environment (for instance as a parameter of CBL_WRITE_SCR_CHARS ).

As a result, whatever code is sent to a supported environment at run time is automatically correct for that environment - even if the environment was unknown when the program was written.

In certain cases, for example, when the environment requires a shift to graphics mode before receiving the graphical character code, the run-time system intervenes and interprets the environment code when necessary.

9.2 Operation

This COBOL system provides the CBL_GET_SCR_LINE_DRAW call-by-name library routine for retrieving environment-specific codes from the run-time system at run time.

CBL_GET_SCR_LINE_DRAW is very flexible, enabling you to:

9.2.1 CBL_GET_SCR_LINE_DRAW

CBL_GET_SCR_LINE_DRAW retrieves environment codes from the run-time system.

You can request CBL_GET_SCR_LINE_DRAW to send you:

The routine requires two parameters:

The function code is always of the same form, but the data (parameter) block is slightly different for different requests. If you are requesting a single character, you must state its generic code.

The call returns two sorts of information:

Individual environment codes can conveniently be assigned to name variables, for example:

         03 horizontal-line pic x.

If you requested all of the 256 environment codes, they are returned as subscripted occurrences of a data item. The environment codes are ordered in the table so that the subscript is the character's generic code. See the section Finding the Character You Want for more information about this.

See the sections Requesting a Table of Character Codes and Requesting an Individual Character Code for information on how to make the calls.

9.2.2 Finding the Character You Want

This section explains how you can determine the generic code (subscript of data item line-draw-character) to use if you know the shape of the graphic character you want.

The following is a selection of line-drawing characters:

Each of them can be described as a cross made out of four strokes, called North, South, West, and East, out from the center. For example, the character:

can be described as a single North, West, and East line, and no South line.

A proprietary code is used to express this kind of description as a single byte:

Thus, the character above is coded as 01 00 01 01 = 69 decimal, or x"45".

This is a logical, convenient, and compact way of describing line-drawing characters. By translating them at run time into something that the current environment understands, applications can be made portable between different environments without changing the source.

9.2.3 Requesting a Table of Character Codes

You can request a single-byte or double-byte version of the code. The following sections show you how to request codes.

9.2.3.1 Requesting a Table of Single-byte Codes

To request a table of single-byte codes:

  1. Declare the following data items in the Working-Storage Section of your program:
    01 chars2-function-code       pic x comp-x.
    01 chars2-parameter-block-0.
       03 line-draw-code          pic x comp-x.
       03                         pic x.
       03 line-draw-character     pic x occurs 255.

    The dummy item before line-draw-character is necessary because we want to refer to a table of items using a subscript in the range 0 through 255, but COBOL subscripts start from 1. By inserting a unnamed data item, with the same PICTURE clause as the recurring item, just before the recurring item, the dummy item is treated as the 0th occurrence of the recurring item.

    This technique requires you to specify the NOBOUND directive when compiling or generating your program. Failure to do so will result in run-time system error 153 "Subscript out of range". Alternatively, you could create a table of 256 occurrences, and always add one to the generic code when referencing the table.

  2. Request the table during initialization by moving 0 to chars2-function-code and making the call:
    call "CBL_GET_SCR_LINE_DRAW" using
                             chars2-function-code
                             chars2-parameter-block-0

    The returned value in line-draw-code tells you what compromises have been made due to the limitations of the current environment. See the section Checking for Substitutions for information on how to find out what substitutions have taken place.

  3. When you need to use an environment code, you can access it using the generic code as a subscript.

    For example, to draw a tee with a double horizontal and single vertical line (generic code 00011010, decimal 26), assuming that a successful call to CBL_GET_SCR_LINE_DRAW has been made, the following code could be used:

    move line-draw-character(26) to character-buffer
    call "CBL_WRITE_SCR_CHARS" using screen-position
                                     character-buffer
                                     string-length.

9.2.3.2 Requesting a Table of Double-byte Codes

To request a table of double-byte codes:

  1. You need the following data items declared in the Working-Storage Section of your program:
      01 chars2-function-code          pic x comp-x.
        01 chars2-parameter-block-1.
           03 line-draw-code           pic x comp-x.
           03                          pic xx.
           03 dbcs-line-draw-character pic xx occurs 255.

    The dummy item before dbcs-line-draw-character is necessary because we want to refer to a table of items using a subscript in the range 0 through 255, but COBOL subscripts start from 1. By inserting a unnamed data item, with the same PICTURE clause as the recurring item, just before the recurring item, the dummy item is treated as the 0th occurrence of the recurring item.

    This technique requires you to specify the NOBOUND directive when compiling or generating your program. Failure to do so will result in run-time system error 153 "Subscript out of range". Alternatively, you could create a table of 256 occurrences, and always add one to the generic code when referencing the table.

  2. Request the table during initialization by moving 1 to chars2-function-code and making the call:
    call "CBL_GET_SCR_LINE_DRAW" using 
                              chars2-function-code
                              chars2-parameter-block-1

    The returned value in line-draw-code tells you what compromises have been made because of the limitations of the current environment. See the section Checking for Substitutions later in this chapter for more information on finding out what substitutions have taken place.

  3. When you need to use an environment code, you can then access it using the generic code as a subscript.

    For example, to draw a tee with a double horizontal and single vertical line (generic code 00011010, decimal 26), assuming that a successful call to CBL_GET_SCR_LINE_DRAW has been made:

    move dbcs-line-draw-character(26) to character-buffer
    call "CBL_WRITE_SCR_CHARS" using screen-position
                                     character-buffer
                                     string length.

9.2.4 Requesting an Individual Character Code

You can request a single-byte or double-byte version of the code. If you need more than one character, you need to arrange to store characters returned, adding suitable items to the Working-Storage Section of your program. For example:

01 character-codes.
   03 top-left-corner       pic x.
   03 bottom-left-corner    pic x.
   03 top-right-corner      pic x.
   03 bottom-right-corner   pic x.
   03 horizontal-line       pic x.
   03 vertical-line         pic x.

The PICTURE clause of each level-03 item is x for single-byte codes, xx for double-byte codes.

You specify the particular character whose environment code you want by quoting its generic code. The following steps show you how to request a code.

9.2.4.1 Requesting a Single Single-byte Code

  1. You need the following data items declared in the Working-Storage Section of your program:
    01 chars2-function-code          pic x comp-x.
    01 chars2-parameter-block-2.
       03 line-draw-code             pic x comp-x.
       03 line-draw-character        pic x. 
  2. Request an individual single-byte character by moving 2 to chars2-function-code.

  3. Move the generic code for the character to line-draw-code.

  4. Make the call:
    call "CBL_GET_SCR_LINE_DRAW" using
                              chars2-function-code
                              chars2-parameter-block-2

    The returned value in line-draw-code tells you what compromises have been made because of the limitations of the current environment. See the section Checking for Substitutions later in this chapter for more information on finding out what substitutions have taken place.

    You need to store the environment code returned in line-draw-character if you intend to use the call again before using the environment code you have just requested. For example:

    move line-draw-character to bottom-left-corner 
  5. When you need a character, you can then refer to it using the appropriate data item name.

9.2.4.2 Requesting a Single Double-byte Code

To request a single double-byte code:

  1. Declare the following data items in the Working-Storage Section of your program:
    01 chars2-function-code            pic x comp-x.
    01 chars2-parameter-block-3.
       03 line-draw-code               pic x comp-x.
       03 dbcs-line-draw-character     pic xx. 
  2. Request an individual double-byte character by moving 3 to chars2-function-code.

  3. Move the generic code for the character to line-draw-code.

  4. Make the call:
    call "CBL_GET_SCR_LINE_DRAW" using
                              chars2-function-code
                              chars2-parameter-block-3

    The returned value in line-draw-code tells you what compromises have been made because of the limitations of the current environment. See the section Checking for Substitutions to find out what substitutions have taken place.

    You need to store the environment code returned in line-draw-character if you intend to use the call again before using the environment code you have just requested. For example:

    move line-draw-character to bottom-left-corner 
  5. When you need a character, you can then refer to it using the appropriate data item name.

9.2.5 Replacing Unavailable Characters

When the current environment tries to represent each of the 256 possible generic line-drawing characters, there are three possibilities:

The run-time system maps the generic codes onto the environment codes, including the best possible mappings for characters that do not have a direct equivalent in the environment. This means that your program does not have to perform any mapping.

This mapping is done automatically whenever you use CBL_GET_SCR_LINE_DRAW. The routine returns information about the mappings that have taken place, as described in the section Checking for Substitutions.

9.2.5.1 Choosing Substitutes to Use

If the current environment is not capable of displaying the character you have requested, the run-time system uses the following rules to determine what character should be displayed in its place:

9.2.5.2 Checking for Substitutions

Some applications need to know if substitutions have taken place. To make this possible, the run-time system returns a single byte, line-draw-code, that contains a value that tells you what mappings have occurred. The least significant three bits (0 through 2) have the following meanings when set to 1:

Bit
Meaning
2 Extended lines are not supported and have been mapped.
1 Double lines are not supported and have been mapped.
0 Single lines are not supported and have been mapped.

The five most significant bits (3 through 7) are currently reserved and your program does not need to check their settings.

Using the value of the bits 0 through 2, and the order of preference for substitution, the values of line-draw-code can be seen to have the following meanings:

Decimal Value
Meaning
7 Extended, single, and double lines are not supported, so were mapped to ASCII characters.
6 Extended and double lines are not supported, so were mapped to single lines.
5 Extended and single lines are not supported, so were mapped to double lines.
4 Extended lines are not supported, so were mapped to single lines.
3 Double and single lines are not supported, so were mapped to extended lines.
2 Double lines are not supported, so were mapped to single lines.
1 Single lines are not supported, so were mapped to double lines.
0 All line types are supported, so no mappings took place.

9.3 Character Graphics Routines

There are two routines to help you find appropriate characters for your character user interfaces, independent of environment:

CBL_GET_SCR_GRAPHICS Get graphics characters
CBL_GET_SCR_LINE_DRAW Get line drawing characters

These routines are described in the following sections.

The COBOL system call-by-name library routines (those of the form CBL_name_name) use type definitions and COBOL CALL prototypes; this helps you to ensure that all calls to these routines are valid. For further information see the section Using the Library Routine TYPEDEFs and CALL Prototypes in the chapter Library Routines in your Programmer's Guide to Writing Programs.

To ensure that the type definitions and CALL protoypes are used by your program, you should include the copyfile $COBDIR/cpylib/cblproto.cpy in your program. cblproto.cpy must be copied before the Identification Division of the program being compiled.

9.3.1 Description of Routines


CBL_GET_SCR_GRAPHICS

Returns operating system independent codes for graphics characters.

Syntax:
call "CBL_GET_SCR_GRAPHICS" using     graphics-params 
                            returning status-code
Parameters:

graphics-params     A group item predefined as cblt-get-scr-graphics-buffer, containing the following subordinate items:
    cblte-gsgb-flag       cblt-x1-compx.
    cblte-gsgb-buf-size   cblt-x2-compx.
    cblte-gsgb-buf.       Group item defined as:
    cblte-gsgb-up-arrow.     Group item defined as:
       cblte-gsgb-up-arrow-dbflag      cblt-x1-compx.
       cblte-gsgb-up-arrow-arrow       cblt-x1-compx.
    cblte-gsgb-down-arrow.   Group item defined as:
       cblte-gsgb-down-arrow-dbflag    cblt-x1-compx.
       cblte-gsgb-down-arrow-arrow     cblt-x1-compx.
    cblte-gsgb-right-arrow.  Group item defined as:
              cblte-gsgb-right-arrow-dbflag   cblt-x1-compx.
              cblte-gsgb-right-arrow-arrow    cblt-x1-compx.
    cblte-gsgb-left-arrow.   Group item defined as:
              cblte-gsgb-left-arrow-dbflag    cblt-x1-compx.
              cblte-gsgb-left-arrow-arrow     cblt-x1-compx.
    cblte-gsgb-maximize.     Group item defined as:
      cblte-gsgb-maximize-dbflag      cblt-x1-compx.
            cblte-gsgb-maximize-char        cblt-x1-compx.
    cblte-gsgb-minimize.     Group item defined as:
              cblte-gsgb-minimize-dbflag      cblt-x1-compx.
              cblte-gsgb-minimize-char        cblt-x1-compx.
    cblte-gsgb-check.        Group item defined as:
       cblte-gsgb-check-dbflag         cblt-x1-compx.
       cblte-gsgb-check-char           cblt-x1-compx.
    cblte-gsgb-restore.      Group item defined as:
       cblte-gsgb-restore-dbflag       cblt-x1-compx.
       cblte-gsgb-restore-char         cblt-x1-compx.
    cblte-gsgb-radio.        Group item defined as:
       cblte-gsgb-radio-dbflag         cblt-x1-compx.
       cblte-gsgb-radio-char           cblt-x1-compx.
    cblte-gsgb-scroll.       Group item defined as:
       cblte-gsgb-scroll-dbflag        cblt-x1-compx.
       cblte-gsgb-scroll-char          cblt-x1-compx.
    cblte-gsgb-rubber-band.  Group item defined as:
       cblte-gsgb-rubber-band-dbflag   cblt-x1-compx.
       cblte-gsgb-rubber-band-char     cblt-x1-compx.
    cblte-gsgb-sysmenu.      Group item defined as:
       cblte-gsgb-sysmenu-char-dbflag  cblt-x1-compx.
       cblte-gsgb-sysmenu-char-char    cblt-x1-compx.
    cblte-gsgb-editor-char.    Group item defined as:
       cblte-gsgb-editor-char-dbflag   cblt-x1-compx.
       cblte-gsgb-editor-char-char     cblt-x1-compx.
    cblte-gsgb-editor-char.    Group item defined as:
       cblte-gsgb-editor-char-dbflag   cblt-x1-compx.
       cblte-gsgb-editor-char-char     cblt-x1-compx.
    cblte-gsgb-hyhelp-tab.     Group item defined as:
       cblte-gsgb-hyhelp-tab-dbflag     cblt-x1-compx.
       cblte-gsgb-ehyhelp-tab-char     cblt-x1-compx.
    cblte-gsgb-hyhelp-btab.    Group item defined as:
       cblte-gsgb-hyhelp-btab-dbflag   cblt-x1-compx.
       cblte-gsgb-ehyhelp-btab-char    cblt-x1-compx.
status-code    See Key in the Preface

On Entry:
cblte-gsgb-flag Type of character code to return:
0 Either single- or double-byte character set as appropriate for the host environment
1 Only single-byte character set (SBCS)
2 Only double-byte character set (DBCS)
cblte-gsgb-buf-size Length of cblte-gsgb-buf in bytes. The normal value of cblte-gsgb-buf-size is 30, although by specifying a smaller value you can request only the graphics values you require.

You must not set cblte-gsgb-buf-size to be greater than the length of cblte-gsgb-buf. If cblte-gsgb-buf-size exceeds the length of cblte-gsgb-buf, the run-time system continues to write to memory past the buffer, which could corrupt other data.

On Exit:
cblte-gsgb-buf-size Number of bytes filled.
cblte-gsgb-buf Character codes for each entry that is completely contained in the cblte-gsgb-buf-size byte count. The contents of any character code which is only partially in the byte count is undefined. Any character codes wholly outside the byte count are ignored.

The byte count should include the whole of any DBCS character-part, even if DBCS is not requested or expected.

For the -dbflg data items, zero indicates single-byte character codes have been returned; a nonzero value is the first byte of the double-byte character returned.

status-code Return status:
0 Success
1 Not all requested codes were available. cblte-gsgb-buf-size contains the number of bytes that were returned.
2 cblte-gsgb-buf could not be filled with the character codes specified (either SBCS or DBCS). In this case, the characters that were not available were filled as though cblte-gsgb-flag was set to 0.
3 Both the errors signalled by status-code = 1 and 2 occurred.

CBL_GET_SCR_LINE_DRAW

Returns a table of values defining the character values required by the run-time system screen output routines to correctly display given line drawing characters.

Syntax:
call "CBL_GET_SCR_LINE_DRAW" using    function-code
                                      line-draw-table
                            returning status-code
Parameters:
function-code            cblt-x1-compx.
Contains one of the following:
0 Request for single-byte line drawing table
1 Request for double-byte line drawing table
2 Request for a single single-byte line drawing code
3 Request for a single double-byte line drawing code
line-draw-table          Group item defined as:
With function-code = 0:
cblte-gsld-draw-code cblt-x1-compx.
cblte-gsld-draw-char Redefines cblte-gsld-dbcs-draw-char cblt-x1-compx occurs n times.

With function-code = 1:

cblte-gsld-draw-code cblt-x1-compx.
cblte-gsld-dbcs-draw-char cblt-x2-compx occurs n times.

With function-code = 2:

cblte-gsld-draw-code cblt-x1-compx.
cblte-gsld-draw-char Redefines cblte-gsld-dbcs-draw-char cblt-x1-compx.

With function-code = 3:

cblte-gsld-draw-code cblt-x1-compx.
cblte-gsld-dbcs-draw-char cblt-x2-compx.
status-code See Key in the Preface
On Entry:

With function-code = 2 or 3:

line-draw-code The offset (shape description) of the character required.
On Exit:
line-draw-code Byte filled in by the run-time system to determine any mapping that has taken place in the table as follows:
bit 7 - 3 Reserved (set to 0)
bit 2 Extended lines not supported - mapped
bit 1 Double lines not supported - mapped
bit 0 Single lines not supported - mapped

For bits 0 through 2, line types are mapped to the first available of single, double, extended or ASCII character.

With function-code = 0:

line-draw-char The single-byte line drawing table. Bytes in the table are arranged as follows:

bits 6 and 7 The North line.
bits 4 and 5 The South line
bits 2 and 3 The West line
bits 0 and 1 The East line

With function-code = 1:

DBCS-line-draw-char

The double-byte line drawing table. Bytes in the table are arranged as follows:

bits 6 and 7 the North line.
bits 4 and 5 the South line
bits 2 and 3 the West line
bits 0 and 1 the East line

With function-code = 2:

line-draw-char The requested single single-byte line drawing code.

With function-code = 3:

DBCS-line-draw-char The requested single double-byte line drawing code.
Comments:

When requesting a single line drawing character (function-code = 2 or 3), the line-draw-code parameter is used to tell the run-time system which character you require. The line-draw-code parameter for a given line-drawing shape can be calculated by splitting a byte into four bit-pairs. Each bit-pair defines the type of line that you want to appear in one of the four directions:

   Bit:   |  7   6  |  5   4  |  3   2  |  1   0  | 
          |  North  |  South  |   West  |   East  |

Each bit-pair can have one of the following values:

00 In the given direction, there is no line
01 There is a single-thickness line
10 There is a double-thickness line
11 There is an extended-type line.

The extended line type is available only for systems which have additional types of line drawing, such as dotted lines. If a system has more than one additional type, only one can be used at a time.

For example, if you wished to find out the screen handler's character code for a line which would define the bottom-left of a box with single thickness sides and a double thickness bottom, you would make the following calculations:

Bit-pairs:

North: 01 (single)
South: 00 (blank)
West: 00 (blank)
East: 10 (double)

This gives the binary value of 01000010 or a decimal value of 66. Therefore, you would move 66 to line-draw-code before calling CBL_GET_SCR_LINE_DRAW in order to obtain the correct character for this shape.

If you use function-code = 0 or 1 to obtain the full line drawing table, a given character can be located in the table using the bit-pair algorithm described above, which yields a numeric value for a given shape. However, by default, COBOL subscripts begin at one, not zero. Therefore, if you use the following construct to obtain the full line drawing table:

     03 line-draw-char       pic x occurs 256 times.

you need to add 1 to the result of the bit-pair algorithm to locate the correct character (and, therefore, need a subscript which is larger than one byte).

However, you can use the following construct to obtain the table:

With function-code = 0:

     03 filler               pic x. 
     03 line-draw-char       pic x occurs 255 times.

With function-code = 1:

     03 filler               pic x(2). 
     03 DBCS-line-draw-char  pic x(2) occurs 255 times.

You must ensure that the NOBOUND Compiler directive is set to enable you to use subscripts 0 to 255, which map directly onto the result from the bit-pair algorithm.


Copyright © 2000 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousIBM PC Character Set IBM PC Display AttributesNext