home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
NOTEPAD2.ZIP
/
NPFONT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-08
|
16KB
|
496 lines
/***************************************************************************\
* npfont.c - notepad font handling
*
* Created by Microsoft Corporation, 1989
\***************************************************************************/
#include <stdlib.h>
#include <string.h>
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
#include <opendlg.h>
#include "notepad.h"
#include "npcmd.h"
#include "search.h"
typedef struct _NAMESTRUCT {
CHAR szFamilyName[FACESIZE];
CHAR szFaceName[FACESIZE];
} NAMESTRUCT;
typedef NAMESTRUCT FAR *PNAMESTRUCT;
typedef struct _FONTSTRUCT {
NAMESTRUCT nms;
SHORT sLastSize;
} FONTSTRUCT;
typedef FONTSTRUCT FAR *PFONTSTRUCT;
typedef struct _SIZESTRUCT {
SHORT sPoints;
LONG lMatch;
} SIZESTRUCT;
typedef SIZESTRUCT FAR *PSIZESTRUCT;
PFONTSTRUCT pfnts = NULL;
PSIZESTRUCT psizes = NULL;
USHORT cbsizes = 0;
SHORT scsizes;
SHORT sCurrFont = -1;
SHORT sCurrSizeIndex = -1;
SHORT sCurrSize;
SHORT sScreenXRes, sScreenYRes;
HWND hwndSizeMenu;
HWND hwndFontMenu;
#define SYSFONTTEXT "System Font"
VOID AutoSelectSize(VOID);
VOID ClearSizeMenu(VOID);
VOID DisableSizeMenu(VOID);
int _CDECL CompareNMS(const void *, const void *);
PSZ CurrFaceName()
{
return((pfnts+sCurrFont)->nms.szFaceName);
}
SHORT CurrFaceSize()
{
return((psizes+sCurrSizeIndex)->sPoints);
}
/**********************************************************************
*
* GetWindowResolution
*
* determines the resolution (in x and y) that fonts on the screen should
* have.
**********************************************************************/
VOID GetWindowResolution(HWND hwnd)
{
HDC hdcScreen;
LONG ldevcaps[2];
BOOL retcd;
hdcScreen = WinQueryWindowDC(hwnd);
retcd = DevQueryCaps(hdcScreen, CAPS_HORIZONTAL_FONT_RES, 2L, ldevcaps);
sScreenXRes = (SHORT)ldevcaps[0];
sScreenYRes = (SHORT)ldevcaps[1];
}
static VOID AddFont(SHORT sIndex, PNAMESTRUCT pnms, MENUITEM FAR *mi)
{
WinSendMsg(hwndFontMenu,MM_INSERTITEM,
MPFROMP(mi),
MPFROMP((pnms==NULL)?SYSFONTTEXT:(pnms->szFaceName)));
if (pnms == NULL) {
lstrcpy((pfnts+sIndex)->nms.szFamilyName, SYSFONTTEXT);
lstrcpy((pfnts+sIndex)->nms.szFaceName, SYSFONTTEXT);
} else {
lstrcpy((pfnts+sIndex)->nms.szFamilyName, pnms->szFamilyName);
lstrcpy((pfnts+sIndex)->nms.szFaceName, pnms->szFaceName);
}
(pfnts+sIndex)->sLastSize = 0;
}
static VOID MakeFontMenu(LONG lFonts, PNAMESTRUCT pnms)
{
MENUITEM mi;
SHORT i;
pfnts = (PFONTSTRUCT)WinAllocMem(hhAppHeap,
(USHORT) ((lFonts + 1) * sizeof(FONTSTRUCT)));
mi.iPosition = MIT_END;
mi.afStyle = MIS_TEXT;
mi.afAttribute = 0;
mi.id = (SUB_FONTS | (0x01));
mi.hwndSubMenu = NULL;
mi.hItem = NULL;
AddFont(0,NULL,(MENUITEM FAR *)&mi);
for (i = 0; i < (SHORT) lFonts; i++) {
mi.iPosition = MIT_END;
mi.afStyle = MIS_TEXT;
mi.afAttribute = 0;
mi.id = (SUB_FONTS | ((i+2) & 0xff));
mi.hwndSubMenu = NULL;
mi.hItem = NULL;
AddFont(i+1,(pnms+i),(MENUITEM FAR *)&mi);
}
SelectFont(1);
}
/**********************************************************************
*
* GetFontMetrics
*
* Given a face name, get the table of font metrics; return as the
* function value the number of entries in the font metrics table;
* as a side effect set the pointer to the allocated table and update
* the value passed by reference for the length of the table. It is
* the caller's responsibility to later WinFreeMem on the pointer
* returned.
**********************************************************************/
SHORT GetFontMetrics(PSZ pszFaceName, PFONTMETRICS *pfms, PSHORT pcbytes)
{
HPS hps;
LONG pcFonts;
LONG cRemFonts;
hps = WinGetPS(hwndNPEdit);
pcFonts = 0;
cRemFonts = GpiQueryFonts(hps,
QF_PUBLIC | QF_PRIVATE,
pszFaceName,
(PLONG) &pcFonts,
(LONG) 0,
NULL);
*pcbytes = (SHORT) (cRemFonts * sizeof(FONTMETRICS));
*pfms = (PFONTMETRICS)WinAllocMem(hhAppHeap,*pcbytes);
pcFonts = cRemFonts;
GpiQueryFonts(hps,
QF_PUBLIC | QF_PRIVATE,
pszFaceName,
(PLONG) &pcFonts,
(LONG) sizeof(FONTMETRICS),
*pfms);
WinReleasePS(hps);
return((SHORT) cRemFonts);
}
BOOL ExistsScrRes(PNAMESTRUCT pnms)
{
SHORT i;
LONG cFonts;
PFONTMETRICS pfms;
SHORT cbytes;
cFonts = GetFontMetrics(pnms->szFaceName, &pfms, &cbytes);
for (i = 0; i < (SHORT) cFonts; i++) {
if (((pfms+i)->sXDeviceRes == sScreenXRes) &&
((pfms+i)->sYDeviceRes == sScreenYRes)) {
WinFreeMem(hhAppHeap, (NPBYTE) OFFSETOF(pfms), (USHORT) cbytes);
return(TRUE);
}
}
WinFreeMem(hhAppHeap, (NPBYTE) OFFSETOF(pfms), (USHORT) cbytes);
return(FALSE);
}
int _CDECL CompareNMS(const void *a, const void *b)
{
return(lstrcmp((PSZ)((PNAMESTRUCT)a)->szFaceName,
(PSZ)((PNAMESTRUCT)b)->szFaceName));
}
LONG EliminateDups(LONG cFonts, PNAMESTRUCT pnms)
{
LONG i, cActual;
cActual = 0;
for (i = 1; i < cFonts; i++) {
if (CompareNMS((void *) (pnms + cActual),
(void *) (pnms + i)) != 0) {
if (ExistsScrRes(pnms+i)) {
cActual++;
if (cActual != i)
LCopyStruct((PCH)(pnms+i),(PCH)(pnms+cActual),sizeof(*pnms));
}
}
}
return(cActual + 1);
}
VOID InitFonts()
{
HPS hps;
LONG cRemFonts;
LONG pcFonts;
LONG cActualFonts;
PNAMESTRUCT pnms;
MENUITEM mi;
if (!GpiLoadFonts(hab,"c:\\os2\\dll\\COURIER.dll"));
if (!GpiLoadFonts(hab,"c:\\os2\\dll\\TIMES.dll"));
if (!GpiLoadFonts(hab,"c:\\os2\\dll\\HELV.fon"));
GetWindowResolution(hwndNPEdit);
WinSendMsg(hwndNPMenu,
MM_QUERYITEM,
MPFROM2SHORT(SUB_SIZES, FALSE),
MPFROMP(&mi));
hwndSizeMenu = mi.hwndSubMenu;
WinSendMsg(hwndNPMenu,
MM_QUERYITEM,
MPFROM2SHORT(SUB_FONTS, FALSE),
MPFROMP(&mi));
hwndFontMenu = mi.hwndSubMenu;
hps = WinGetPS(hwndNPEdit);
pcFonts = 0;
cRemFonts = GpiQueryFonts(hps,
QF_PUBLIC | QF_PRIVATE,
NULL,
(PLONG) &pcFonts,
(LONG) 0,
NULL);
pnms = (PNAMESTRUCT) WinAllocMem(hhAppHeap,
(USHORT) (cRemFonts*sizeof(NAMESTRUCT)));
pcFonts = cRemFonts;
GpiQueryFonts(hps,
QF_PUBLIC | QF_PRIVATE,
NULL,
(PLONG) &pcFonts,
(LONG) sizeof(NAMESTRUCT),
(PFONTMETRICS)pnms);
WinReleasePS(hps);
qsort((VOID *) OFFSETOF(pnms), (size_t) cRemFonts,
sizeof(*pnms), CompareNMS);
cActualFonts = EliminateDups(cRemFonts, pnms);
MakeFontMenu(cActualFonts,pnms);
}
VOID ClearSizeMenu(VOID)
{
SHORT i;
sCurrSizeIndex = -1;
i = 1;
while (LONGFROMMR(WinSendMsg(hwndSizeMenu, MM_REMOVEITEM,
MPFROMSHORT(SUB_SIZES | (i++ & 0xff)),
NULL)))
;
}
/**********************************************************************
* DisableSizeMenu(VOID)
*
* Called to destroy the existing size menu and replace it with a single
* disabled entry "no sizes available" -- primarily for use with the
* system font
**********************************************************************/
VOID DisableSizeMenu(VOID)
{
MENUITEM mi;
ClearSizeMenu();
mi.iPosition = MIT_END;
mi.afStyle = MIS_TEXT;
mi.afAttribute = MIA_DISABLED;
mi.id = (SUB_SIZES | 0x01);
mi.hwndSubMenu = NULL;
mi.hItem = NULL;
WinSendMsg(hwndSizeMenu,MM_INSERTITEM,
MPFROMP(&mi),
MPFROMP("No Sizes Available"));
}
VOID AddSize(SHORT sPointSize, SHORT sIndex)
{
MENUITEM mi;
CHAR buff[18];
mi.iPosition = MIT_END;
mi.afStyle = MIS_TEXT;
mi.afAttribute = 0;
mi.id = (SUB_SIZES | ((sIndex+1) & 0xff));
mi.hwndSubMenu = NULL;
mi.hItem = NULL;
WinSendMsg(hwndSizeMenu,MM_INSERTITEM,
MPFROMP(&mi),
MPFROMP(itoa(sPointSize,buff,10)));
}
VOID BuildSizeTable(FONTMETRICS pfms[], LONG cFonts)
{
SHORT i;
SHORT sMatches;
if (psizes != NULL) {
WinFreeMem(hhAppHeap, (NPBYTE) OFFSETOF(psizes),
(USHORT) cbsizes);
psizes = NULL;
}
sMatches = 0;
for (i = 0; i < (SHORT) cFonts; i++) {
if ((pfms[i].sXDeviceRes == sScreenXRes) &&
(pfms[i].sYDeviceRes == sScreenYRes))
sMatches++;
}
cbsizes = sMatches * sizeof(SIZESTRUCT);
scsizes = sMatches;
if (scsizes == 0) {
DisableSizeMenu();
return;
}
ClearSizeMenu();
psizes = (PSIZESTRUCT)WinAllocMem(hhAppHeap, cbsizes);
sMatches = 0;
for (i = 0; i < (SHORT) cFonts; i++) {
if ((pfms[i].sXDeviceRes == sScreenXRes) &&
(pfms[i].sYDeviceRes == sScreenYRes)) {
(psizes+sMatches)->sPoints = pfms[i].sNominalPointSize;
(psizes+sMatches)->lMatch = pfms[i].lMatch;
AddSize((pfms[i].sNominalPointSize)/10,sMatches);
sMatches++;
}
}
}
/**********************************************************************
*
* SelectSizeIndex
*
* Given a 1-based index into the size table, do whatever's necessary
* to set the current font to that size.
* A value <0 will always select the system font/size.
**********************************************************************/
BOOL SelectSizeIndex(SHORT sIndex)
{
FATTRS fattrs;
if (sCurrSizeIndex >= 0) {
WinSendMsg(hwndNPMenu,
MM_SETITEMATTR,
MPFROM2SHORT((SUB_SIZES|((sCurrSizeIndex+1)&0xff)),TRUE),
MPFROM2SHORT(MIA_CHECKED,0));
}
sCurrSizeIndex = sIndex-1;
if ((sIndex < 0) || (sIndex>scsizes)) {
sCurrSize = -1;
} else {
sCurrSize = (psizes+sCurrSizeIndex)->sPoints;
WinSendMsg(hwndNPMenu,
MM_SETITEMATTR,
MPFROM2SHORT((SUB_SIZES|((sIndex)&0xff)),TRUE),
MPFROM2SHORT(MIA_CHECKED,MIA_CHECKED));
}
(pfnts+sCurrFont)->sLastSize = sCurrSize;
if (sCurrSize < 0) {
return((BOOL) LONGFROMMR(WinSendMsg(hwndNPEdit,
EM_SETFONT,
NULL,
0L)));
} else {
fattrs.usRecordLength = sizeof(fattrs);
fattrs.fsSelection = 0;
fattrs.lMatch = (psizes+sIndex-1)->lMatch;
lstrcpy(fattrs.szFacename, (pfnts+sCurrFont)->nms.szFaceName);
fattrs.idRegistry = 0;
fattrs.usCodePage = 0;
fattrs.lMaxBaselineExt = 0;
fattrs.lAveCharWidth = 0;
fattrs.fsType = 0;
fattrs.fsFontUse = 0;
return((BOOL) LONGFROMMR(WinSendMsg(hwndNPEdit,
EM_SETFONT,
MPFROMP((PFATTRS)&fattrs),
0L)));
}
}
/**********************************************************************
* SelectSize
*
* Given a point size, selects the font of that size for the current face.
* If no such size exists, returns FALSE.
* A value <0 selects the system font/size.
**********************************************************************/
BOOL SelectSize(SHORT sPoints)
{
SHORT i;
if (sPoints == -1) {
SelectSizeIndex(-1);
return(TRUE);
}
for (i=0; i<scsizes; i++) {
if ((psizes+i)->sPoints == sPoints) {
SelectSizeIndex(i+1);
return(TRUE);
}
}
return(FALSE);
}
/**********************************************************************
*
* AutoSelectSize
*
* Tries to intelligently select the size when a new font is chosen.
* Attempts, in order:
* 1. The last size the font was used with
* 2. The size used in the font just deselected
* 3. The smallest size for that font.
**********************************************************************/
VOID AutoSelectSize(VOID)
{
if ((pfnts+sCurrFont)->sLastSize > 0) {
if (SelectSize((pfnts+sCurrFont)->sLastSize))
return;
}
if (sCurrSize > 0)
if (SelectSize(sCurrSize))
return;
SelectSizeIndex(1);
}
/**********************************************************************
*
* SelectFont
*
* Given a 1-based index into the Font table, sets the current font
* to that font, and sets the size (and thus the font used in the
* edit control) as needed.
*
**********************************************************************/
VOID SelectFont(SHORT sFontIndex)
{
LONG cRemFonts;
PFONTMETRICS pfms;
SHORT cbytes;
if (sCurrFont >= 0) {
WinSendMsg(hwndNPMenu,
MM_SETITEMATTR,
MPFROM2SHORT((SUB_FONTS|((sCurrFont+1)&0xff)),TRUE),
MPFROM2SHORT(MIA_CHECKED,0));
}
sCurrFont = sFontIndex-1;
WinSendMsg(hwndNPMenu,
MM_SETITEMATTR,
MPFROM2SHORT((SUB_FONTS|(sFontIndex&0xff)),TRUE),
MPFROM2SHORT(MIA_CHECKED,MIA_CHECKED));
if (sCurrFont == 0) {
DisableSizeMenu();
SelectSize(-1);
} else {
cRemFonts = GetFontMetrics((pfnts+sCurrFont)->nms.szFaceName,
&pfms, &cbytes);
BuildSizeTable((FONTMETRICS near *) OFFSETOF(pfms), cRemFonts);
AutoSelectSize();
WinFreeMem(hhAppHeap, (NPBYTE) OFFSETOF(pfms), (USHORT) cbytes);
}
}