Windows GDI printing typeface management

The Sample.Windows.Printer item in the dm,devices, file is a printer device driver template that controls the behavior of the various @() functions associated with Windows GDI printing.

Note: To use this item, it must be copied to another item with an ID no longer than 12 characters (see assignfq (Windows) command).

Typeface selection control

The @(-340) function allows you to define which Windows typefaces will be available when setting font characteristics for Windows GDI printed output (specifically when invoking the @(-321) function which retrieves the typeface name by its relative position within the @(-340) control string). The example below illustrates the @(-340) control string of comma-delimited fields:

f,x1b,x01,x40,ly,a,c],tf1,c],tf2,c],tf3,c],tf4,c],tf5,c],tf6,c],tf7,c],tf8,c],
tf9,c],tf10,c],tf11,c],lf12,m20,c'Courier New',],c'Lucida Console',],
c'OCR A Extended',],c'Arial',],c'Calibri',],c'Verdana',],c'Times New Roman',]
,c'Century',],c'Lucida Bright',],c'Brush Script MT',],c'Edwardian Script ITC
',],c'Freestyle Script',],c'French Script MT',],c'Kunstler Script',],
c'Old English Text MT',],c'Stencil',],c'Onyx',],c'Playbill',],c'Ravie',]
,c'Showcard Gothic',],x02,<
Note: We have broken this string apart (below) to illustrate the control string fields that pertain to this discussion.
f,x1b,x01,x40,ly,a,c],tf1,c],tf2,c],tf3,c],tf4,c],tf5,c],tf6,c],tf7,c]
,tf8,c],tf9,c],tf10,c],tf11,c],lf12,m20
,c'Courier New',]
,c'Lucida Console',]
,c'OCR A Extended',]
,c'Arial',]
,c'Calibri',]
,c'Verdana',]
,c'Times New Roman',]
,c'Century',]
,c'Lucida Bright',]
,c'Brush Script MT',]
,c'Edwardian Script ITC',]
,c'Freestyle Script',]
,c'French Script MT',]
,c'Kunstler Script',]
,c'Old English Text MT',]
,c'Stencil',]
,c'Onyx',]
,c'Playbill',]
,c'Ravie',]
,c'Showcard Gothic',]
,x02,<

The 31st comma-delimited field above (known as the max typeface field) indicates to the function the number of available typefaces. In this example, m20 indicates that there are 20 typefaces available. Immediately following this field are the actual typefaces presented as a series of two-field pairs. The first is c'Courier New' followed by a field containing a right square bracket. This defines Courier New as the first typeface.  The second is Lucida Console, the third is OCA A Extended, and so on.

Adding, replacing and deleting typefaces

You can use an editor to change the names of the typefaces, thereby replacing one font with another. You can also use an editor to add or remove typefaces from the list of available fonts. However, be aware that as you add or remove fonts from the list, the max typeface field must be updated to indicate the new number of available typefaces. For example, if you were to add 2 new typefaces to the control string illustrated above, you would also need to change the max typeface field to m22.

It is also possible (and probably preferable) to modify the control string programmatically. The example illustrates a subroutine allows you to add, delete and replace typefaces in winGDI devices file item:

subroutine winGDI_updTypeface.sub(deviceID,Typeface,Action)
*
* Add/delete/replace a typeface in a winGDI devices file item
*
* Arguments:
*   deviceID  ID of the item in dm,devices,
*   Typeface  Typeface name to be added to @(-340) string
*   Action    "add" to add
*             "delete" to delete
*             "replace##" to replace the ##th entry
*
  if not(assigned(deviceID)) then deviceID = ""
  if not(assigned(Typeface)) then Typeface = ""
  if not(assigned(Action)) then Action = ""
*
  if Typeface = "" then abort "Typeface name is null"
  begin case
    case Action[1,3] = "add"
    case Action[1,3] = "del"
    case Action[1,3] = "rep"
    case 1; abort "No valid Action defined"
  end case
*
  open 'dm,devices,' to f.devices else abort 201,'dm,devices,'
  read devItem from f.devices,deviceID else
    abort 202,'dm,devices, ':deviceID
  end
*
  tfStr = ""   ;*   Extract @(-340) attribute from devices item
* PROGRAMMER'S   If the @(-340) string prefix in the devices file
* NOTE:          item ever changes, make sure to change the prefix.
  tfStr_prefix  = "f,x1b,x01,x40,ly,a,c],tf1,c],tf2,c],tf3,c],"
  tfStr_prefix := "tf4,c],tf5,c],tf6,c],tf7,c],tf8,c],tf9,c],"
  tfStr_prefix := "tf10,c],tf11,c],lf12,m"
  tfStr_pf_len  = len(tfStr_prefix)
  tfStr_suffix  = "x02,<"
*
  devItem_max = dcount(devItem, char(254))
  devItem_ax  = 0
  for devItem_x = 1 to devItem_max
    if devItem<devItem_x>[1,tfStr_pf_len] = tfStr_prefix then
      devItem_ax = devItem_x
      tfStr = devItem<devItem_x>
      devItem_x = devItem_max
    end
  next devItem_x
*
  if tfStr = "" then abort "devices item typeface string not found"
*
  tfStr = tfStr[tfStr_pf_len+1,999]
  tfMax = field(tfStr,",",1)
  tfNames = ""
  for tfName_x = 1 to tfMax
    wIdx = index(tfStr,",C'",tfName_x)
    wNme = field(tfStr[wIdx,999],"'",2)
    tfNames<tfName_x> = wNme
  next tfName_x
*
  updateFlag = 0
  begin case
    case Action[1,3] = "add"
      locate Typeface in tfNames setting tfIdx else
        tfMax += 1
        tfNames<tfMax> = Typeface
        updateFlag = 1
      end
    case Action[1,3] = "del"
      locate Typeface in tfNames setting tfIdx then
        tfMax -= 1
        tfNames = delete(tfNames,tfIdx)
        updateFlag = 1
      end
    case Action[1,3] = "rep"
      tfIdx = Action 'cn'
      if tfIdx >= 1 and tfIdx <= tfMax then
        tfNames<tfIdx> = Typeface
        updateFlag = 1
      end
  end case
*
  if updateFlag then
    tfStr = tfStr_prefix : tfMax : ","
    for tfName_x = 1 to tfMax
      tfStr := "c'" : tfNames<tfName_x> : "',],"
    next tfName_x
    tfStr := tfStr_suffix
    devItem<devItem_ax> = tfStr
    write devItem on f.devices,deviceID
  end
  close f.devices
*
SubroutineMainExit:
  return
*
* End of source

Simple one-line examples of programs that call the above routine are illustrated below. Note that these examples assume the presence of a dm,devices, item called WIN_GDI_PRTR (which is a copy of the Sample.Windows.Printer item).

To add a typeface:

call winGDI_updTypeface.sub("WIN_GDI_PRTR","Arial","Add")

To delete a typeface:

call winGDI_updTypeface.sub("WIN_GDI_PRTR","Arial","Delete")

To replace a typeface:

call winGDI_updTypeface.sub("WIN_GDI_PRTR","Arial","Replace12")

Available Windows typefaces

To view the list of typefaces that are available to windows GDI printers, open the control panel on the D3 Windows server and double-click the Fonts item. The Font Name (not the filename) is the name you use when setting up a new font. You only need to reference the base name of the font name. For example, for the font name Cambria Bold Italic (True Type) you need only use Cambria since the Windows print driver will use your other font weight and italic @() functions to choose among the various Cambria fonts available in Windows.