NT4/private/windows/win4help/winhelp/fontlyr.c
2020-09-30 17:12:29 +02:00

1074 lines
26 KiB
C

/*****************************************************************************
*
* FONTLYR.C
*
* Copyright (C) Microsoft Corporation 1990-1994
* All Rights reserved.
*
******************************************************************************
*
* Module Intent
*
* Contains WINDOWS specific font selection routines.
*
*****************************************************************************/
#include "help.h"
#pragma hdrstop
#include <ctype.h>
#include "inc\fontlyr.h"
#include "resource.h"
static HFONT STDCALL CreateFontHandle(QDE, QFOFFTAB, int, int);
static BOOL STDCALL FSetForeColor(QDE, COLORREF);
static int INLINE GetFontFamilyName(int);
static VOID STDCALL InitSpecialColors(VOID);
static GH STDCALL ReadFontTable(PDB);
static VOID STDCALL SelSplTextColor(int, QDE);
static VOID STDCALL SetBkAndForeColor(QCF, QDE);
static int CALLBACK EnumHelpFont(CONST LOGFONT *, CONST TEXTMETRIC *, DWORD, LPARAM);
static DWORD rgbJump;
static DWORD rgbDefinition;
static DWORD rgbString;
static DWORD rgbIFJump;
static DWORD rgbIFDefinition;
#define EXACT_CHARSET 0x10000000
#define DIFFERENT_CHARSET 0x20000000
#ifndef NO_PRAGMAS
#pragma data_seg(".text", "CODE")
#endif
static const char txtSymbolFontName[] = "Symbol";
static const char txtWingDingsFontName[] = "WingDings";
static const char txtSystemFontName[] = "System";
#ifndef NO_PRAGMAS
#pragma data_seg()
#endif
/***************************************************************************
*
- Name: InitSpecialColors
-
* Purpose: This function reads the values for the text color from the
* WIN.INI ion. It acquires memory for storing the information
* about created fonts to reduce font creation overhead.
*
* Arguments: QDE - Pointer to the Display Environment(DE)
*
* Returns: TRUE iff successful.
*
***************************************************************************/
static BOOL fInitSpecialColors;
static VOID STDCALL InitSpecialColors( VOID )
{
if (!fInitSpecialColors) {
rgbJump = RgbGetProfileQch("JUMPCOLOR", RGB(0, 128, 0));
rgbDefinition = RgbGetProfileQch("POPUPCOLOR", rgbJump);
rgbString = RgbGetProfileQch("MACROCOLOR", rgbJump);
rgbIFJump = RgbGetProfileQch("IFJUMPCOLOR", rgbJump);
rgbIFDefinition = RgbGetProfileQch("IFPOPUPCOLOR", rgbDefinition);
fInitSpecialColors = TRUE;
}
}
/*******************
**
** Name: RgbGetProfileQch
**
** Purpose:
**
**
**
** Arguments:
**
** Returns:
**
*******************/
DWORD STDCALL RgbGetProfileQch(PCSTR psz, DWORD rgbDefault)
{
char rgch[40];
char *p;
int r, g, b;
// If zero bytes copied, return immediately
if (!GetProfileString(txtIniHelpSection, psz, txtZeroLength, rgch, sizeof(rgch)))
return rgbDefault;
p = rgch;
while (!isdigit((BYTE) *p) && *p)
p++;
if (rgch[0] == '\0')
return rgbDefault;
r = atoi(p);
while (isdigit((BYTE) *p) && *p)
p++;
while (!isdigit((BYTE) *p) && *p)
p++;
if (rgch[0] == '\0')
return rgbDefault;
g = atoi(p);
while (isdigit((BYTE) *p) && *p)
p++;
while (!isdigit((BYTE) *p) && *p)
p++;
if (rgch[0] == '\0')
return 0xFFFFFFFF;
b = atoi(p);
return RGB(r, g, b);
}
/***************************************************************************
*
- Name: LoadFontTablePdb
-
* Purpose: This function acquires memory for storing the font table
* inforamtion as read from the file.
*
* Arguments: pdb - Pointer to the file database struct
*
* Returns: TRUE if successful.
*
***************************************************************************/
BOOL STDCALL FLoadFontTablePdb(PDB pdb)
{
InitSpecialColors();
// if not already created, attempt to read it from the file.
if (!PDB_HFNTTABLE(pdb)) {
PDB_HFNTTABLE(pdb) = ReadFontTable(pdb);
if (!PDB_HFNTTABLE(pdb))
return FALSE;
}
return TRUE;
}
/***************************************************************************
*
- Name: FInitFntInfoQde
-
* Purpose:
* Initialize the QDE's font cache from.
*
* Arguments:
* qde - pointer to DE
*
* Returns:
*
***************************************************************************/
BOOL STDCALL FInitFntInfoQde(QDE qde)
{
QSFNTINFO qSFntInfo;
int iT;
// assume the worst. If there is no font table in the DE, and we can't
// create it, then there is no point in creating the cache
QDE_HSFNTINFO(qde) = NULL;
if (!QDE_HFNTTABLE(qde))
if (!FLoadFontTablePdb(QDE_PDB (qde)))
return FALSE;
// Alloc the cache. If we cannot, we must also tube the fint table info
// in the DB.
QDE_HSFNTINFO(qde) = GhAlloc(LMEM_FIXED | LMEM_ZEROINIT,
sizeof(SFNTINFO) * SFNTINFOMAX);
if (!QDE_HSFNTINFO(qde)) {
FreeGh (QDE_HFNTTABLE(qde));
QDE_HFNTTABLE(qde) = NULL;
return FALSE;
}
// We have our cache. Init it to appropriately.
qSFntInfo = (QSFNTINFO) PtrFromGh (QDE_HSFNTINFO(qde));
for (iT = 0; iT < SFNTINFOMAX; iT++, qSFntInfo++)
// all other fields already nil. NOTE: relies on ZEROINIT above, and the
// fact that nil values for those fields are 0.
qSFntInfo->Idx = ifntNil;
return TRUE;
}
/***************************************************************************
*
- Name: DestroyFontTablePdb
-
* Purpose: This function delets the font table
*
* Arguments: pdb - pointer to database info
*
* Returns: TRUE if successful
*
***************************************************************************/
void STDCALL DestroyFontTablePdb(PDB pdb)
{
if (PDB_HFNTTABLE(pdb)) {
FreeGh(PDB_HFNTTABLE(pdb));
PDB_HFNTTABLE(pdb) = NULL;
}
}
/***************************************************************************
*
- Name: DestroyFntInfoQde
-
* Purpose: This function deletes the information
* about available fonts created previously.
*
* Arguments: QDE - far pointer to display environment.
*
* Returns: TRUE iff successful
*
***************************************************************************/
void STDCALL DestroyFntInfoQde(QDE qde)
{
QSFNTINFO qSFntInfo;
int iT;
if (QDE_HSFNTINFO(qde)) {
qSFntInfo = (QSFNTINFO) PtrFromGh (QDE_HSFNTINFO(qde));
for (iT = 0; iT < SFNTINFOMAX; iT++, qSFntInfo++)
SafeDeleteObject(qSFntInfo->hFnt);
FreeGh(QDE_HSFNTINFO(qde));
QDE_HSFNTINFO(qde) = NULL;
}
}
/***************************************************************************
*
- Name: SelFont
-
* Purpose: This function select the Idxth font in font table in the
* specified display surface.
*
*
* Arguments: qde - far pointer to a display environment.
* iIdx - Index into the font table defining a set of font
* attributes.
*
*
* Returns: Nothing.
*
***************************************************************************/
// REVIEW: Could change this to SelSplAttrFonr(qde, ifnt, 0);
void STDCALL SelFont(QDE qde, int ifnt)
{
HFONT hFnt;
ASSERT(qde->hdc);
hFnt = GetFontHandle(qde, ifnt, 0);
if (!hFnt)
hFnt = GetStockObject(SYSTEM_FONT);
if (hFnt) {
if (SelectObject(qde->hdc, hFnt)) {
qde->ifnt = ifnt;
return;
}
}
// REVIEW: Is this the right error message?
Error(wERRS_OOM_NO_FONT, wERRA_DIE); // We should never get here
}
/***************************************************************************
*
- Name: SelSplAttrFont
-
* Purpose: This function selects the Idxth font in the font table with
* the given attr to the display surface.
*
* Arguments: qde - Far pointer to the Display Environment(DE)
* iIdx - Index to the font table defining the current font
* characteristics.
* iAttr - special attribute to be associated with the Idxth
* font of the font table.
*
* Returns: TRUE if successful.
*
***************************************************************************/
BOOL STDCALL SelSplAttrFont(QDE qde, int ifnt, int iAttr)
{
HFONT hFnt;
ASSERT(!FInvisibleHotspot(iAttr));
ASSERT(qde->hdc);
hFnt = GetFontHandle(qde, ifnt, iAttr);
if (!hFnt)
hFnt = GetStockObject(SYSTEM_FONT);
if (hFnt) {
if (SelectObject(qde->hdc, hFnt) != NULL) {
qde->ifnt = ifnt;
return TRUE;
}
}
Error(wERRS_OOM_NO_FONT, wERRA_DIE);
return FALSE; // never get here
}
/***************************************************************************
*
- Name: GetFontHandle
-
* Purpose: This function looks into the FontInfo stored to see if a
* font was created with the current characteristics before and
* currently available. If so, it return the previously created
* font handle. If not, it creates one with the given
* characteristics specified in the font table stored in the
* given QDE.
*
* Arguments: qde - long pointer to Display Environment
* iIdx - Index to the font table defining the current font
* characteristics.
* Attr - Font for special text or normal text
*
* Returns: Font handle which will be NULL in case of error
*
***************************************************************************/
HFONT STDCALL GetFontHandle(QDE qde, int iIdx, int iAttr)
{
QSFNTINFO qSFntInfo, qSFntInfoTemp;
QFOFFTAB pTable;
int iT, CurIdx = ifntNil;
HFONT hFnt = NULL;
DWORD UseCount;
QCF qcf;
/*
* If we weren't able to allocate a font table, then everything is in
* the system font.
*/
if (QDE_HFNTTABLE(qde) == NULL)
return GetStockObject(SYSTEM_FONT);
ASSERT(QDE_HSFNTINFO(qde));
qSFntInfo = qSFntInfoTemp = (QSFNTINFO) PtrFromGh(QDE_HSFNTINFO(qde));
// check if the font was already created?
for (iT = 0; iT < SFNTINFOMAX; iT++, qSFntInfoTemp++) {
if ((qSFntInfoTemp->Idx == iIdx) && (qSFntInfoTemp->Attr == iAttr)) {
// font is already created
hFnt = qSFntInfoTemp->hFnt;
CurIdx = iT;
break;
}
}
pTable = (QFOFFTAB) PtrFromGh(QDE_HFNTTABLE(qde));
if (!hFnt) {
if (iIdx >= pTable->iFntEntryCount) {
/*
* If we get an index bigger than the font table size set the
* index to something legal.
*/
iIdx = max(0, pTable->iFntEntryCount - 1);
}
// Create the font handle as it is not available
hFnt = CreateFontHandle(qde, pTable, iIdx, iAttr);
ASSERT(hFnt);
if (hFnt && (qSFntInfo != NULL)) {
// store the handle for the future reference
UseCount = 0;
for (iT = 0, qSFntInfoTemp = qSFntInfo; iT < SFNTINFOMAX; iT++,
qSFntInfoTemp++) {
// Is the entry empty?
if (!qSFntInfoTemp->hFnt) {
qSFntInfoTemp -> hFnt = hFnt;
qSFntInfoTemp -> Idx = iIdx;
qSFntInfoTemp -> Attr = iAttr;
CurIdx = iT;
break;
}
else if (UseCount < qSFntInfoTemp->UseCount) {
CurIdx = iT;
UseCount = qSFntInfoTemp->UseCount;
}
}
if (iT == SFNTINFOMAX) {
// least used font has to be deleted.
qSFntInfoTemp = (qSFntInfo + CurIdx);
SafeDeleteObject(qSFntInfoTemp->hFnt);
qSFntInfoTemp -> hFnt = hFnt; // store new font handle
qSFntInfoTemp -> Idx = iIdx; // store new font index
qSFntInfoTemp -> Attr = iAttr;
}
}
}
else {
// set color alone
if (!FVisibleHotspot(iAttr)) {
qcf = (((QCF) (((PBYTE) pTable) + pTable->iFntEntryTabOff)) + iIdx);
SetBkAndForeColor(qcf, qde);
}
else {
// if color, then only select the special color for special text
SelSplTextColor(iAttr, qde);
}
}
if (qSFntInfo != NULL && hFnt) {
// Update the use count
for (iT = 0; iT < SFNTINFOMAX; iT++, qSFntInfo++) {
if (iT == CurIdx)
qSFntInfo->UseCount = 0;
else
qSFntInfo->UseCount++;
}
}
ASSERT(hFnt);
return hFnt;
}
/***************************************************************************
*
- Name: CreateFontHandle
-
* Purpose: This function is called when a logical font is to be created
* with the given characteristics in Character Format (CF)
* structure.
*
* Arguments: qde - QDE which the font is created for
* pTable - pointer to start of font info table
* idx - Font number for the font table.
* Attr - Attribute of text for which font is selected.
*
* Returns: Font handle or NULL on error.
*
***************************************************************************/
static HFONT STDCALL CreateFontHandle(QDE qde, QFOFFTAB pTable, int idx,
int Attr)
{
LOGFONT logfont;
int dyHeight;
QCF qcf;
BOOL fUnderline;
BYTE bCharSet;
int cbFontName =
(QDE_HHDR(qde).wVersionNo >= wVersion40) ?
MAX4_FONTNAME : MAX3_FONTNAME;
#ifdef _DEBUG
PSTR pszFontName;
#endif
qcf = ((QCF) (((PBYTE) pTable) + pTable->iFntEntryTabOff) + idx);
ASSERT(QDE_HHDR(qde).wVersionNo < wVersion40 || qcf->wIdFntName <= cCharSets);
// set color information
if (!FVisibleHotspot(Attr))
SetBkAndForeColor(qcf, qde);
else {
// if color, then only select the special color for special text
SelSplTextColor(Attr, qde);
}
// convert the size from half points to pixel
ASSERT(YAspectMul);
if (qde->deType == dePrint)
dyHeight = MulDiv(qde->wYAspectMul, qcf->bSize, 144);
else
dyHeight = MulDiv(qde->wYAspectMul, qcf->bSize + cntFlags.iFontAdjustment,
144);
/*
* WinHelp 3.1 files used a maximum facename of 20 characters, and
* didn't have a mechanism for including the charset. WinHelp 4.0 files
* increase the facename to 31 characters. For backwards compatibility,
* if we have a version 3.1 help file, we either use SYMBOL_CHARSET for
* Symbol and WingDing fonts, or else we use the system's current
* charset. Note that both 3.1 and 4.0 use LF_FACESIZE to determine the
* number of bytes to move, even though this may not be the actual size
* of the name used.
*/
#ifdef _DEBUG
pszFontName = ((LPSTR) pTable) + pTable->iFntNameTabOff + (cbFontName * qcf->wIdFntName);
#endif
MoveMemory((LPSTR) logfont.lfFaceName,
((LPSTR) pTable) + pTable->iFntNameTabOff +
(cbFontName * qcf->wIdFntName), LF_FACESIZE - 1);
logfont.lfFaceName[LF_FACESIZE - 1] = '\0';
if (qde->pdb->aCharSets)
bCharSet = qde->pdb->aCharSets[qcf->wIdFntName];
else if (WCmpiSz(txtSymbolFontName, logfont.lfFaceName) == 0 ||
WCmpiSz(txtWingDingsFontName, logfont.lfFaceName) == 0)
bCharSet = SYMBOL_CHARSET;
else
bCharSet = (BYTE) defcharset;
// BUGBUG: this should be in core -- it allows WinHelp
#if defined(DBCS) || defined(BIDI)
{
DWORD charset = bCharSet;
EnumFonts(qde->hdc, logfont.lfFaceName, EnumHelpFont, (LPARAM) &charset);
if (HIWORD(charset))
bCharSet = LOBYTE(charset); // this may or may not have changed
else {
// The font is not available, so use the system font
#ifdef _DEBUG
char szMsg[256];
wsprintf(szMsg, "The font \042%s\042 is unavailable.", logfont.lfFaceName);
DBWIN(szMsg);
#endif // _DEBUG
strcpy(logfont.lfFaceName, txtSystemFontName);
bCharSet = (BYTE) defcharset;
}
}
#endif // DBCS
#ifdef _DEBUG
if (_stricmp(logfont.lfFaceName, "arial") == 0)
ASSERT(bCharSet != 2); // arial can't have a symbol font
#endif
// Underline all visible hotspots that aren't glossaries.
fUnderline = qcf->fAttr & fUNDERLINE ||
(FVisibleHotspot(Attr) && !FNoteHotspot(Attr));
logfont.lfHeight = -dyHeight; // Desired ascent size
logfont.lfWidth = 0;
logfont.lfEscapement = 0;
logfont.lfOrientation = 0;
logfont.lfWeight = (qcf->fAttr & fBOLD) ? FW_BOLD : FW_NORMAL;
logfont.lfItalic = (BYTE) (qcf->fAttr & fITALIC);
logfont.lfUnderline = (BYTE) fUnderline;
logfont.lfStrikeOut = (BYTE) (qcf->fAttr & fSTRIKETHROUGH);
logfont.lfCharSet = bCharSet;
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logfont.lfQuality = DEFAULT_QUALITY;
logfont.lfPitchAndFamily = (BYTE) (DEFAULT_PITCH |
GetFontFamilyName(qcf->bFntType));
if (qcf->fAttr & fSMALLCAPS && qde->hdc != NULL) {
// Do the rough approximation
logfont.lfHeight = 2 * logfont.lfHeight / 3;
}
return CreateFontIndirect(&logfont);
}
/***************************************************************************
*
- Name: ReadFontTable
-
* Purpose: This function reads the font table from the help file system
* and return a global handle to the data.
*
* Arguments: pdb - pointer to the database information
*
* Returns: return the handle to the Font Info Table, or NULL if an
* occurs.
*
***************************************************************************/
static GH STDCALL ReadFontTable(PDB pdb)
{
HF hf;
#ifdef _X86_ // REVIEW LYNN
GH ghTemp;
LONG lSize;
#else
SDFF_FILEID isdff;
LONG lcbDiskSize;
GH ghDisk;
GH ghMem;
QB qbDisk;
QB qbMem;
FONTHEADER fontheader;
LONG lcbMemSize;
BOOL bVersion3;
int cbMem;
#endif
if ((hf = HfOpenHfs(PDB_HFS(pdb), "|FONT", fFSOpenReadOnly)) == NULL) {
GiveFSError();
return NULL;
}
#ifdef _X86_ // REVIEW LYNN
if ((ghTemp = GhAlloc(GPTR, lSize = LcbSizeHf(hf))) == NULL) {
Error(wERRS_OOM, wERRA_RETURN);
}
else if (LcbReadHf(hf, PtrFromGh(ghTemp), lSize) != lSize) {
GiveFSError();
FreeGh(ghTemp);
ghTemp = 0;
}
RcCloseHf(hf); // Ignore errors on close
return ghTemp;
}
#else
isdff = ISdffFileIdHf(hf);
lcbDiskSize = LcbSizeHf(hf);
if ((ghDisk = GhAlloc(GPTR, lcbDiskSize)) == NULL)
{
Error(wERRS_OOM, wERRA_RETURN);
goto fonttable_close;
}
qbDisk = (QB) PtrFromGh( ghDisk );
if (LcbReadHf( hf, qbDisk, lcbDiskSize) != lcbDiskSize)
{
GiveFSError();
goto fonttable_free_and_close;
}
qbDisk += LcbMapSDFF(isdff, SE_FONTHEADER, &fontheader, qbDisk);
cbMem = (fontheader.iFntEntryTabOff - fontheader.iFntNameTabOff)/fontheader.iFntNameCount;
ASSERT(cbMem==MAX3_FONTNAME || cbMem == MAX4_FONTNAME);
if (bVersion3 = cbMem == MAX3_FONTNAME) {
lcbMemSize = sizeof(FONTHEADER) + fontheader.iFntNameCount * sizeof(FONTNAMEREC)
+ fontheader.iFntEntryCount * sizeof(CF);
}else {
lcbMemSize = sizeof(FONTHEADER) + fontheader.iFntNameCount * sizeof(FONTNAMEREC1)
+ fontheader.iFntEntryCount * sizeof(CF);
}
if ((ghMem = GhAlloc(GPTR, lcbMemSize)) == NULL)
{
Error(wERRS_OOM, wERRA_RETURN);
goto fonttable_close;
}
qbMem = (QB) PtrFromGh(ghMem);
*((QFONTHEADER)qbMem)++ = fontheader;
if (bVersion3) {
while (fontheader.iFntNameCount-- > 0) {
qbDisk += LcbMapSDFF(isdff, SE_FONTNAMEREC, qbMem, qbDisk);
qbMem += sizeof(FONTNAMEREC);
}
}else {
while (fontheader.iFntNameCount-- > 0) {
qbDisk += LcbMapSDFF(isdff, SE_FONTNAMEREC1, qbMem, qbDisk);
qbMem += sizeof(FONTNAMEREC1);
}
}
while( fontheader.iFntEntryCount-- > 0)
{
qbDisk += LcbMapSDFF(isdff, SE_CF, qbMem, qbDisk);
qbMem += sizeof(CF);
}
fonttable_free_and_close:
if (ghDisk != NULL)
FreeGh(ghDisk);
fonttable_close:
RcCloseHf( hf ); //* Ignore errors on close *
return ghMem;
}
#endif
/***************************************************************************
*
- Name: SelBkAndForeColor
-
* Purpose: This function sets the background and foreground color for
* the given display environment.
*
* Arguments: qcf - pointer to current Character Format
* hds - Handle to display environment.
*
* Returns: Nothing.
*
***************************************************************************/
static VOID STDCALL SetBkAndForeColor(QCF qcf, QDE qde)
{
QRGBS qcol;
DWORD rgbBack, rgb;
// Set the color
qcol = (QRGBS) &(qcf->bBackCol);
rgbBack = RGB(qcol->red, qcol->green, qcol->blue);
if (rgbBack == coDEFAULT || cntFlags.fOverColor || fDisableAuthorColors)
rgbBack = qde->coBack;
SetBkColor(qde->hdc, rgbBack);
qcol = (QRGBS) &(qcf->bForeCol);
rgb = RGB(qcol->red, qcol->green, qcol->blue);
if (rgb == coDEFAULT || cntFlags.fOverColor || fDisableAuthorColors) {
if (rgb != coDEFAULT && rgbBack == qde->coBack)
SetTextColor(qde->hdc, rgb);
else
FSetForeColor(qde, qde->coFore);
}
else
FSetForeColor(qde, (rgb == qde->coFore) ? rgb : GetNearestColor(qde->hdc, rgb));
}
/***************************************************************************
*
- Name: SelSplTextColor
-
* Purpose: This function sets the background and foreground color for
* the given special type of text.
*
* Arguments: iAttr - Special Text attribute type
* hds - Handle to display environment.
*
* Returns: Nothing.
*
***************************************************************************/
static VOID STDCALL SelSplTextColor(int iAttr, QDE qde)
{
DWORD rgb;
ASSERT(FVisibleHotspot(iAttr));
SetBkColor(qde->hdc, qde->coBack);
switch(iAttr) {
case AttrJumpFnt:
case AttrJumpHFnt:
rgb = GetNearestColor(qde->hdc, rgbJump);
break;
case AttrDefFnt:
case AttrDefHFnt:
rgb = GetNearestColor(qde->hdc, rgbDefinition);
break;
case AttrSzFnt:
rgb = GetNearestColor(qde->hdc, rgbString);
break;
case AttrIFJumpHFnt:
rgb = GetNearestColor(qde->hdc, rgbIFJump);
break;
case AttrIFDefHFnt:
rgb = GetNearestColor(qde->hdc, rgbIFDefinition);
break;
default:
ASSERT( FALSE );
rgb = GetNearestColor(qde->hdc, rgbJump);
break;
}
FSetForeColor(qde, rgb);
}
/***************************************************************************
*
- Name: GetFontFamilyName(idx)
-
* Purpose: This function return the Font Family Constant to be used at
* the time of the creation of the font.
*
* Arguments: Idx - Font Family constant indepent of the environment.
*
* Returns: Return the font constant depending on the environment.
*
***************************************************************************/
static int INLINE GetFontFamilyName(int Idx)
{
switch(Idx) {
case MODERNFONT:
return FF_MODERN;
case SWISSFONT:
return FF_SWISS;
case SCRIPTFONT:
return FF_SCRIPT;
case ROMANFONT:
return FF_ROMAN;
case DECORATIVEFONT:
return FF_DECORATIVE;
default:
return FF_DONTCARE;
}
}
/***************************************************************************
*
- Name: FSetForeColor
-
* Purpose:
*
* Arguments:
*
* Returns:
*
***************************************************************************/
static BOOL STDCALL FSetForeColor(QDE qde, COLORREF rgbFore)
{
ASSERT(rgbFore == GetNearestColor(qde->hdc, rgbFore));
// Make certain foreground and background colors aren't identical
if (rgbFore != qde->coFore && rgbFore == GetNearestColor(qde->hdc, qde->coBack))
rgbFore = qde->coFore;
SetTextColor(qde->hdc, rgbFore);
return TRUE;
}
/***************************************************************************
*
- Name: GiveFSError
-
* Purpose: Informs the user of a file system error
*
* Arguments: Nothing.
*
* Returns: Nothing.
*
***************************************************************************/
void STDCALL GiveFSError(void)
{
int wErr;
switch (RcGetFSError()) {
case rcOutOfMemory:
wErr = wERRS_OOM;
break;
case rcDiskFull:
wErr = wERRS_DiskFull;
break;
default:
wErr = wERRS_FSReadWrite;
break;
}
Error(wErr, wERRA_RETURN);
}
#if 0
#define GWW_HINSTANCE (-6)
WORD STDCALL GetWindowLong(HWND, INT16);
#endif
/*******************
-
- Name: DisplayAnnoSym
*
* Purpose: Displays the annotation symbol (temporary)
*
* Arguments:
*
*
* Returns:
*
******************/
VOID STDCALL DisplayAnnoSym(HWND hwnd, HDC hdc, int x, int y, int fHot)
{
HBITMAP hbmp, hbmpOld;
HDC hdcMem;
BITMAP bmp;
RECT rct;
COLORREF clr;
hdcMem = CreateCompatibleDC(hdc);
if (!hdcMem)
return;
hbmp = LoadBitmap(hInsNow, MAKEINTRESOURCE(IDBMP_ANNO));
if (!hbmp) {
DeleteDC(hdcMem);
return;
}
hbmpOld = SelectObject(hdcMem, hbmp);
ASSERT(hbmpOld);
GetObject(hbmp, sizeof(BITMAP), &bmp);
/*
* Since the bitmap is monochrome, we set the foreground color so that
* the "black" of the bitmap will be changed to the foreground color.
*/
clr = SetTextColor(hdc, rgbJump);
BitBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
if (fHot) {
rct.top = y;
rct.left = x;
rct.bottom = y + bmp.bmHeight;
rct.right = x + bmp.bmWidth;
InvertRect(hdc, &rct);
}
SetTextColor(hdc, clr);
if (hbmpOld)
SelectObject(hdcMem, hbmpOld);
DeleteObject(hbmp);
DeleteDC(hdcMem);
}
/***************************************************************************
FUNCTION: GetCharset
PURPOSE: Retrieve the charset for the specified font
PARAMETERS:
qde display environment
idx font index
RETURNS: charset for the specified font
COMMENTS: If necessary, we could probably remove the QDE parameter
and just get whatever the current window's QDE is.
MODIFICATION DATES:
***************************************************************************/
BYTE STDCALL GetCharset(QDE qde, int idx)
{
QFOFFTAB pTable = (QFOFFTAB) PtrFromGh(QDE_HFNTTABLE(qde));
QCF qcf;
LOGFONT logfont;
int cbFontName =
(QDE_HHDR(qde).wVersionNo >= wVersion40) ?
MAX4_FONTNAME : MAX3_FONTNAME;
#ifdef _DEBUG
PSTR pszFontName;
#endif
qcf = (((QCF) (((PBYTE) pTable) + pTable->iFntEntryTabOff)) + idx);
ASSERT(QDE_HHDR(qde).wVersionNo < wVersion40 || qcf->wIdFntName <= cCharSets);
#ifdef _DEBUG
pszFontName = ((LPSTR) pTable) + pTable->iFntNameTabOff + (cbFontName * qcf->wIdFntName);
#endif
if (qde->pdb->aCharSets)
return qde->pdb->aCharSets[qcf->wIdFntName];
/*
* WinHelp 3.1 files used a maximum facename of 20 characters, and
* didn't have a mechanism for including the charset. WinHelp 4.0 files
* increase the facename to 31 characters. For backwards compatibility,
* if we have a version 3.1 help file, we either use SYMBOL_CHARSET for
* Symbol and WingDing fonts, or else we use the system's current
* charset. Note that both 3.1 and 4.0 use LF_FACESIZE to determine the
* number of bytes to move, even though this may not be the actual size
* of the name used.
*/
MoveMemory((LPSTR) logfont.lfFaceName,
((LPSTR) pTable) + pTable->iFntNameTabOff +
(cbFontName * qcf->wIdFntName), LF_FACESIZE - 1);
logfont.lfFaceName[LF_FACESIZE - 1] = '\0';
if (WCmpiSz(txtSymbolFontName, logfont.lfFaceName) == 0 ||
WCmpiSz(txtWingDingsFontName, logfont.lfFaceName) == 0)
return SYMBOL_CHARSET;
else
#ifdef DBCS
return (fDBCS ? (BYTE) defcharset : ANSI_CHARSET);
#else
return (BYTE) defcharset;
#endif
}
#if defined(DBCS) || defined(BIDI)
static int STDCALL EnumHelpFont(CONST LOGFONT * lpLogFont, CONST TEXTMETRIC * lpTextMetrics,
DWORD nFontType, LPARAM lpData)
{
DWORD* pdw = (DWORD*) lpData;
if (LOBYTE(*pdw == lpTextMetrics->tmCharSet)) {
*pdw |= EXACT_CHARSET;
return FALSE; // we have the charset we need, so stop enumerating
}
#ifdef _DEBUG
{
char szMsg[256];
wsprintf(szMsg, "Changing charset from %u to %u", (DWORD) LOBYTE(*pdw),
(DWORD) lpTextMetrics->tmCharSet);
DBWIN(szMsg);
}
#endif
*pdw = lpTextMetrics->tmCharSet | DIFFERENT_CHARSET;
return FALSE;
}
#endif