Category : Files from Magazines
Archive   : VOL11N21.ZIP
Filename : FONTLIST.C
FONTLIST.C -- Font Lister for OS/2 2.0 Presentation Manager
(c) Charles Petzold, 1992
-------------------------------------------------------------*/
#define INCL_WIN
#define INCL_GPI
#include
#include
#include
#include
#include "fontlist.h"
MRESULT EXPENTRY ClientWndProc (HWND, ULONG, MPARAM, MPARAM) ;
int main (void)
{
static CHAR szClientClass [] = "FontList" ;
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_SHELLPOSITION | FCF_TASKLIST |
FCF_MENU | FCF_HORZSCROLL ;
HAB hab ;
HMQ hmq ;
HWND hwndFrame, hwndClient ;
QMSG qmsg ;
hab = WinInitialize (0) ;
hmq = WinCreateMsgQueue (hab, 0) ;
WinRegisterClass (hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0) ;
hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
&flFrameFlags, szClientClass,
"Font Lister", 0L,
NULLHANDLE, ID_RESOURCE, &hwndClient) ;
while (WinGetMsg (hab, &qmsg, NULLHANDLE, 0, 0))
WinDispatchMsg (hab, &qmsg) ;
WinDestroyWindow (hwndFrame) ;
WinDestroyMsgQueue (hmq) ;
WinTerminate (hab) ;
return 0 ;
}
/* Functions for obtaining the printer DC and PS
----------------------------------------------*/
HDC OpenDefaultPrinterDC (HAB hab)
{
static CHAR achPrnData[256] ;
static DRIVDATA driv = { sizeof (DRIVDATA) } ;
CHAR achDefPrnName[33], *pchDelimiter ;
DEVOPENSTRUC dop ;
// Obtain default printer name and remove semicolon
PrfQueryProfileString (HINI_PROFILE, "PM_SPOOLER",
"PRINTER", ";",
achDefPrnName, sizeof achDefPrnName) ;
if ((pchDelimiter = strchr (achDefPrnName, ';')) != NULL)
*pchDelimiter = '\0' ;
if (achDefPrnName[0] == '\0')
return DEV_ERROR ;
// Obtain information on default printer
PrfQueryProfileString (HINI_PROFILE, "PM_SPOOLER_PRINTER",
achDefPrnName, ";;;;",
achPrnData, sizeof achPrnData) ;
// Parse printer information string
if ((pchDelimiter = strchr (achPrnData, ';')) == NULL)
return DEV_ERROR ;
dop.pszDriverName = pchDelimiter + 1 ;
if ((pchDelimiter = strchr (dop.pszDriverName, ';')) == NULL)
return DEV_ERROR ;
dop.pszLogAddress = pchDelimiter + 1 ;
*(dop.pszLogAddress + strcspn (dop.pszLogAddress, ",;")) = '\0' ;
*(dop.pszDriverName + strcspn (dop.pszDriverName, ",;")) = '\0' ;
// Fill DRIVDATA structure if necessary
if ((pchDelimiter = strchr (dop.pszDriverName, '.')) != NULL)
{
*pchDelimiter = '\0' ;
strncpy (driv.szDeviceName, pchDelimiter + 1,
sizeof (driv.szDeviceName)) ;
dop.pdriv = &driv ;
}
else
dop.pdriv = NULL ;
// Set data type to "std"
dop.pszDataType = "PM_Q_STD" ;
// Open printer device context
return DevOpenDC (hab, OD_INFO, "*", 4L, (PDEVOPENDATA) &dop, 0L) ;
}
HPS CreatePrinterPS (HAB hab, HDC hdcPrinter)
{
SIZEL sizlPage ;
sizlPage.cx = 0 ;
sizlPage.cy = 0 ;
return GpiCreatePS (hab, hdcPrinter, &sizlPage,
PU_PELS | GPIF_DEFAULT |
GPIT_MICRO | GPIA_ASSOC) ;
}
/* Macro and functions for formatting the data
--------------------------------------------*/
#define FORMAT(field, format) iLen += sprintf (pchBuffer + iLen, \
" " #field format "\n", \
pfm1->##field, \
pfm2->##field) ;
void FormatData (CHAR * pchBuffer, PFONTMETRICS pfm1, PFONTMETRICS pfm2)
{
INT iLen ;
iLen = 0 ;
FORMAT (szFamilyname, ": %s") ;
FORMAT (szFacename, ": %s\n") ;
FORMAT (idRegistry, ": %6hu") ;
FORMAT (usCodePage, ": %6hu\n") ;
FORMAT (lEmHeight, ": %6ld %6ld") ;
FORMAT (lXHeight, ": %6ld %6ld") ;
FORMAT (lMaxAscender, ": %6ld %6ld") ;
FORMAT (lMaxDescender, ": %6ld %6ld") ;
FORMAT (lLowerCaseAscent, ": %6ld %6ld") ;
FORMAT (lLowerCaseDescent, ": %6ld %6ld") ;
FORMAT (lInternalLeading, ": %6ld %6ld") ;
FORMAT (lExternalLeading, ": %6ld %6ld") ;
FORMAT (lAveCharWidth, ": %6ld %6ld") ;
FORMAT (lMaxCharInc, ": %6ld %6ld") ;
FORMAT (lEmInc, ": %6ld %6ld") ;
FORMAT (lMaxBaselineExt, ": %6ld %6ld\n") ;
FORMAT (sCharSlope, ": %04hX") ;
FORMAT (sInlineDir, ": %04hX") ;
FORMAT (sCharRot, ": %04hX\n") ;
FORMAT (usWeightClass, ": %6hu") ;
FORMAT (usWidthClass, ": %6hu\n") ;
FORMAT (sXDeviceRes, ": %6hd") ;
FORMAT (sYDeviceRes, ": %6hd\n") ;
FORMAT (sFirstChar, ": %6hd") ;
FORMAT (sLastChar, ": %6hd") ;
FORMAT (sDefaultChar, ": %6hd") ;
FORMAT (sBreakChar, ": %6hd\n") ;
FORMAT (sNominalPointSize, ": %6hd") ;
FORMAT (sMinimumPointSize, ": %6hd") ;
FORMAT (sMaximumPointSize, ": %6hd\n") ;
FORMAT (fsType, ": %04hX") ;
FORMAT (fsDefn, ": %04hX") ;
FORMAT (fsSelection, ": %04hX") ;
FORMAT (fsCapabilities, ": %04hX\n") ;
FORMAT (lSubscriptXSize, ": %6ld %6ld") ;
FORMAT (lSubscriptYSize, ": %6ld %6ld") ;
FORMAT (lSubscriptXOffset, ": %6ld %6ld") ;
FORMAT (lSubscriptYOffset, ": %6ld %6ld") ;
FORMAT (lSuperscriptXSize, ": %6ld %6ld") ;
FORMAT (lSuperscriptYSize, ": %6ld %6ld") ;
FORMAT (lSuperscriptXOffset, ": %6ld %6ld") ;
FORMAT (lSuperscriptYOffset, ": %6ld %6ld") ;
FORMAT (lUnderscoreSize, ": %6ld %6ld") ;
FORMAT (lUnderscorePosition, ": %6ld %6ld") ;
FORMAT (lStrikeoutSize, ": %6ld %6ld") ;
FORMAT (lStrikeoutPosition, ": %6ld %6ld\n") ;
FORMAT (sKerningPairs, ": %6hd") ;
FORMAT (sFamilyClass, ": %6hd\n") ;
FORMAT (lMatch, ": %6ld\n") ;
FORMAT (FamilyNameAtom, ": %6lu") ;
FORMAT (FaceNameAtom, ": %6lu\n") ;
FORMAT (panose.bFamilyType, ": %6hd") ;
FORMAT (panose.bSerifStyle, ": %6hd") ;
FORMAT (panose.bWeight, ": %6hd") ;
FORMAT (panose.bProportion, ": %6hd") ;
FORMAT (panose.bContrast, ": %6hd") ;
FORMAT (panose.bStrokeVariation, ": %6hd") ;
FORMAT (panose.bArmStyle, ": %6hd") ;
FORMAT (panose.bLetterform, ": %6hd") ;
FORMAT (panose.bMidline, ": %6hd") ;
FORMAT (panose.bXHeight, ": %6hd") ;
FORMAT (panose.abReserved[0], ": %6hd") ;
FORMAT (panose.abReserved[1], ": %6hd") ;
}
BOOL SetDataInWindow (HWND hwndEdit, PFONTMETRICS pfm1, PFONTMETRICS pfm2)
{
CHAR * pchBuffer ;
if (NULL == (pchBuffer = (CHAR *) malloc (10000)))
return FALSE ;
FormatData (pchBuffer, pfm1, pfm2) ;
WinSetWindowText (hwndEdit, pchBuffer) ;
free (pchBuffer) ;
return TRUE ;
}
/* Function for enumerating all fonts in device units and decipoints
----------------------------------------------------------------- */
LONG GetAllFonts (HPS hps, PFONTMETRICS * ppfm1, PFONTMETRICS * ppfm2)
{
HDC hdc ;
LONG lFonts, xDis, yDis, xRes, yRes ;
PFONTMETRICS pfm1, pfm2 ;
SIZEL sizl ;
// Find number of fonts
lFonts = 0 ;
lFonts = GpiQueryFonts (hps, QF_PUBLIC, NULL, &lFonts, 0, NULL) ;
if (lFonts == 0)
return 0 ;
// Allocate memory for FONTMETRICS structures
pfm1 = (PFONTMETRICS) calloc (lFonts, sizeof (FONTMETRICS)) ;
if (pfm1 == NULL)
return 0 ;
pfm2 = (PFONTMETRICS) calloc (lFonts, sizeof (FONTMETRICS)) ;
if (pfm2 == NULL)
{
free (pfm1) ;
return 0 ;
}
// Get font information in device units
GpiQueryFonts (hps, QF_PUBLIC, NULL, &lFonts,
sizeof (FONTMETRICS), pfm1) ;
// Switch world coordinates to decipoints
hdc = GpiQueryDevice (hps) ;
DevQueryCaps (hdc, CAPS_WIDTH, 1, &xDis) ;
DevQueryCaps (hdc, CAPS_HEIGHT, 1, &yDis) ;
DevQueryCaps (hdc, CAPS_HORIZONTAL_FONT_RES, 1, &xRes) ;
DevQueryCaps (hdc, CAPS_VERTICAL_FONT_RES, 1, &yRes) ;
sizl.cx = (720 * xDis + 0.5) / xRes ;
sizl.cy = (720 * yDis + 0.5) / yRes ;
GpiSetPS (hps, &sizl, PU_ARBITRARY) ;
// Get font information in decipoints
GpiQueryFonts (hps, QF_PUBLIC, NULL, &lFonts,
sizeof (FONTMETRICS), pfm2) ;
* ppfm1 = pfm1 ;
* ppfm2 = pfm2 ;
return lFonts ;
}
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
static FATTRS fat = { sizeof (FATTRS), 0, 0, "System Monospaced" } ;
static HAB hab ;
static HWND hwndEdit, hwndMenu, hwndScroll ;
static LONG lFonts, lFont ;
static PFONTMETRICS pfm1, pfm2 ;
static SHORT sDevice = IDM_SCREEN ;
HDC hdc, hdcPrinter ;
HPS hps, hpsPrinter ;
LONG l, xRes, yRes ;
switch (msg)
{
case WM_CREATE:
hab = WinQueryAnchorBlock (hwnd) ;
// Create MLE window
hwndEdit = WinCreateWindow (hwnd, WC_MLE, NULL,
WS_VISIBLE | MLS_VSCROLL | MLS_READONLY,
0, 0, 0, 0, hwnd, HWND_TOP, 1, NULL, NULL) ;
// Get the array of FONTMETRICS structures
hps = WinGetPS (hwnd) ;
lFonts = GetAllFonts (hps, & pfm1, & pfm2) ;
// Set the edit control for a system monospaced font
hdc = GpiQueryDevice (hps) ;
DevQueryCaps (hdc, CAPS_HORIZONTAL_FONT_RES, 1, &xRes) ;
DevQueryCaps (hdc, CAPS_VERTICAL_FONT_RES, 1, &yRes) ;
WinReleasePS (hps) ;
for (l = 0 ; l < lFonts ; l++)
if (!strcmp (pfm1[l].szFacename, fat.szFacename) &&
pfm1[l].sXDeviceRes == xRes &&
pfm1[l].sYDeviceRes == yRes)
{
fat.lMaxBaselineExt = pfm1[l].lMaxBaselineExt ;
fat.lAveCharWidth = pfm1[l].lAveCharWidth ;
}
WinSendMsg (hwndEdit, MLM_SETFONT, (MPARAM) & fat, NULL) ;
// Set the first FONTMETRIC as the edit text
if (lFonts > 0)
SetDataInWindow (hwndEdit, pfm1, pfm2) ;
// Set horizontal scrollbar range
hwndScroll = WinWindowFromID (WinQueryWindow (hwnd, QW_PARENT),
FID_HORZSCROLL) ;
WinSendMsg (hwndScroll, SBM_SETSCROLLBAR,
MPFROM2SHORT (lFont, 0),
MPFROM2SHORT (0, lFonts - 1)) ;
// Get menu window handle
hwndMenu = WinWindowFromID (WinQueryWindow (hwnd, QW_PARENT),
FID_MENU) ;
return 0 ;
case WM_SIZE:
// Set new MLE window size
WinSetWindowPos (hwndEdit, NULLHANDLE,
0, 0, SHORT1FROMMP (mp2), SHORT2FROMMP (mp2),
SWP_MOVE | SWP_SIZE) ;
return 0 ;
case WM_COMMAND:
// Menu commands -- get new font data
WinCheckMenuItem (hwndMenu, sDevice, FALSE) ;
sDevice = COMMANDMSG(&msg)->cmd ;
WinCheckMenuItem (hwndMenu, sDevice, TRUE) ;
if (lFonts > 0)
{
free (pfm1) ;
free (pfm2) ;
}
switch (COMMANDMSG(&msg)->cmd)
{
case IDM_SCREEN:
hps = WinGetPS (hwnd) ;
lFonts = GetAllFonts (hps, & pfm1, & pfm2) ;
WinReleasePS (hps) ;
break ;
case IDM_PRINTER:
hdcPrinter = OpenDefaultPrinterDC (hab) ;
hpsPrinter = CreatePrinterPS (hab, hdcPrinter) ;
lFonts = GetAllFonts (hpsPrinter, & pfm1, & pfm2) ;
GpiDestroyPS (hpsPrinter) ;
DevCloseDC (hdcPrinter) ;
break ;
}
WinSendMsg (hwndScroll, SBM_SETSCROLLBAR,
MPFROM2SHORT (lFont = 0, 0),
MPFROM2SHORT (0, lFonts - 1)) ;
if (lFonts > 0)
SetDataInWindow (hwndEdit, pfm1, pfm2) ;
return 0 ;
case WM_HSCROLL:
// Display different font in MLE control
switch (SHORT2FROMMP (mp2))
{
case SB_LINELEFT: lFont -= 1 ; break ;
case SB_PAGELEFT: lFont -= 8 ; break ;
case SB_LINERIGHT: lFont += 1 ; break ;
case SB_PAGERIGHT: lFont += 8 ; break ;
case SB_SLIDERPOSITION:
lFont = SHORT1FROMMP (mp2) ;
break ;
default:
return 0 ;
}
lFont = max (0, min (lFont, lFonts - 1)) ;
WinSendMsg (hwndScroll, SBM_SETPOS, MPFROMSHORT (lFont), NULL) ;
if (lFonts > 0)
SetDataInWindow (hwndEdit, pfm1 + lFont, pfm2 + lFont) ;
return 0 ;
case WM_CHAR:
switch (CHARMSG(&msg)->vkey)
{
case VK_LEFT:
case VK_RIGHT:
return WinSendMsg (hwndScroll, msg, mp1, mp2) ;
case VK_UP:
case VK_DOWN:
case VK_PAGEUP:
case VK_PAGEDOWN:
return WinSendMsg (hwndEdit, msg, mp1, mp2) ;
}
return 0 ;
case WM_DESTROY:
if (lFonts > 0)
{
free (pfm1) ;
free (pfm2) ;
}
WinSendMsg (hwndEdit, MLM_SETFONT, NULL, NULL) ;
return 0 ;
}
return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/