mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
592 lines
14 KiB
592 lines
14 KiB
/*----------------------------------------------------------------------------
|
|
* *
|
|
* CHARATTR.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1989-1995 *
|
|
* All Rights reserved. *
|
|
* *
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
#include "stdafx.h"
|
|
#include "cfontmap.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define SIZE_FONT_TABLE 41
|
|
#define FNT_TABLE_INCREMENT 11
|
|
|
|
enum {
|
|
iModernFont = 1,
|
|
iRomanFont,
|
|
iSwissFont,
|
|
iScriptFont,
|
|
iDecorativeFont,
|
|
};
|
|
|
|
typedef struct{
|
|
PSTR szFntName;
|
|
int iFntFamily;
|
|
} FT, *QFT;
|
|
|
|
/*
|
|
* This is the list of font names which can be forced via the
|
|
* OPT_FORCEFONT option in the .HPJ file. 13-Oct-1993 [ralphw] Added the
|
|
* names with mixed-case.
|
|
*/
|
|
|
|
static FT ftTab[] = {
|
|
"Arial", iSwissFont,
|
|
"ATHENS", iDecorativeFont,
|
|
"Bookman", iRomanFont,
|
|
"Courier New", iModernFont,
|
|
"COURIER", iModernFont,
|
|
"GENEVA", iSwissFont,
|
|
"HELV", iSwissFont,
|
|
"HELVETICA", iSwissFont,
|
|
"LONDON", iDecorativeFont,
|
|
"MODERN", iModernFont,
|
|
"MONACO", iModernFont,
|
|
"ROMAN", iRomanFont,
|
|
"Times New Roman", iRomanFont,
|
|
"TIMES", iRomanFont,
|
|
"TMS RMN", iRomanFont
|
|
};
|
|
|
|
#define wFTabEntryMac 14
|
|
|
|
static QIFNTENT qInpFntTab;
|
|
static int iInpFntTabEntCount;
|
|
|
|
static RGBTRIPLE* qInpColTab;
|
|
static int iInpColTabEntCount;
|
|
|
|
static QOFNTENT qFntTab; // Font Table to be outputted to file
|
|
static int cFntTableEntries; // Current max No. of entries in table
|
|
static int cFntTabCur; // Current count of font entries (MUST be 16-bits)
|
|
static BYTE aTmpCharSets[MAX_CHARSETS];
|
|
|
|
typedef struct{
|
|
char szFntName[MAX3_FONTNAME];
|
|
} FNTNAME, *QFNTNAME;
|
|
|
|
static PSTR pFntName;
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* VProcFontTableInfo()
|
|
*
|
|
* Description:
|
|
* This function stores the font information and forms a unique list of
|
|
* font names used in the help file.
|
|
*
|
|
* Arguments:
|
|
* 1. pointer to the font table information obtained from RTF reader.
|
|
*
|
|
* Returns:
|
|
* NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
void STDCALL VProcFontTableInfo(FNTBL* qfnttbl)
|
|
{
|
|
QIFNTENT qinpfte;
|
|
int iT;
|
|
|
|
PFTE4 qfte;
|
|
|
|
iInpFntTabEntCount = qfnttbl->cfte;
|
|
if (qInpFntTab)
|
|
lcFree(qInpFntTab);
|
|
qInpFntTab = (QIFNTENT) lcCalloc(
|
|
(iInpFntTabEntCount * sizeof(IFNTENT)));
|
|
|
|
ASSERT(qInpFntTab != NULL);
|
|
|
|
// Default font name
|
|
|
|
// iT = GetFontNameId((PSTR) GetStringResource(IDS_DEF_FONT));
|
|
|
|
// Don't get default font name, since we won't know the charset
|
|
|
|
for (iT = 0, qinpfte = qInpFntTab, qfte = (PFTE4) &(qfnttbl->rgfte[0]);
|
|
iT < qfnttbl->cfte; iT++, qfte++, qinpfte++) {
|
|
qinpfte->wIdFntName = GetFontNameId(qfte->szName);
|
|
qinpfte->bFntType = (char) IMapFontType(qfte->tokType);
|
|
qinpfte->iFntId = qfte->fid;
|
|
#ifdef _DEBUG
|
|
int cbCharSets = lcSize(paCharSets);
|
|
#endif
|
|
if (lcSize(paCharSets) <= qinpfte->wIdFntName - 1)
|
|
paCharSets = (PBYTE) lcReAlloc(paCharSets, qinpfte->wIdFntName + 1);
|
|
#ifdef _DEBUG
|
|
// Need these because VC can't display most structure pointers
|
|
|
|
BYTE bCharSet = qfte->charset;
|
|
PSTR pszFontName = qfte->szName;
|
|
int idFontName = qinpfte->wIdFntName - 1;
|
|
int idFontId = qinpfte->iFntId;
|
|
#endif
|
|
|
|
paCharSets[qinpfte->wIdFntName - 1] = qfte->charset;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* GetFontNameId( szName, qiId )
|
|
*
|
|
* Description:
|
|
* This function stores the font name into the font table and returns
|
|
* the font id with which the font will be referred in the help file then on.
|
|
*
|
|
* Arguments:
|
|
* 1. font name.
|
|
* 2. pointer to the font id.
|
|
*
|
|
* Returns:
|
|
* NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
int STDCALL GetFontNameId(PSTR pszName)
|
|
{
|
|
if (!options.pszForceFont) { // if force font option is OFF?
|
|
if (!ptblFontNames)
|
|
ptblFontNames = new CTable;
|
|
SzTrimSz(pszName);
|
|
|
|
UINT pos;
|
|
if ((pos = ptblFontNames->IsStringInTable(pszName)) <= 0) {
|
|
if (lstrlen(pszName) > MAX4_FONTNAME - 1) {
|
|
// error already reported
|
|
return 0; // use default font
|
|
}
|
|
pos = ptblFontNames->AddString(pszName);
|
|
}
|
|
return pos;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* IGetFmtNo()
|
|
*
|
|
* Description:
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
* NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
int STDCALL IGetFmtNo(CF* pcf)
|
|
{
|
|
static int iT, iT2;
|
|
static QOFNTENT qfte = NULL, qfte2 = NULL;
|
|
|
|
if (qFntTab == NULL || (cFntTabCur >= cFntTableEntries))
|
|
qFntTab = (QOFNTENT) QResizeTable(qFntTab,
|
|
cFntTabCur, (int*) &cFntTableEntries,
|
|
sizeof(OFNTENT), SIZE_FONT_TABLE, FNT_TABLE_INCREMENT);
|
|
ASSERT(qFntTab != NULL);
|
|
|
|
if (qfte2 && qfte2->fAttr == pcf->fAttr &&
|
|
qfte2->wIdFntName == (WORD) (pcf->wIdFntName -1) &&
|
|
qfte2->bSize == pcf->bSize &&
|
|
qfte2->bFntType == pcf->bFntType &&
|
|
memcmp(&qfte2->bForeCol, &pcf->bForeCol, sizeof(RGBTRIPLE)) == 0 &&
|
|
memcmp(&qfte2->bBackCol, &pcf->bBackCol, sizeof(RGBTRIPLE)) == 0)
|
|
return iT2;
|
|
|
|
else if (qfte && qfte->fAttr == pcf->fAttr &&
|
|
qfte->wIdFntName == (WORD) (pcf->wIdFntName -1) &&
|
|
qfte->bSize == pcf->bSize &&
|
|
qfte->bFntType == pcf->bFntType &&
|
|
memcmp(&qfte->bForeCol, &pcf->bForeCol, sizeof(RGBTRIPLE)) == 0 &&
|
|
memcmp(&qfte->bBackCol, &pcf->bBackCol, sizeof(RGBTRIPLE)) == 0)
|
|
return iT;
|
|
|
|
iT2 = iT;
|
|
qfte2 = qfte;
|
|
|
|
// find the match
|
|
|
|
for (iT = 0, qfte = qFntTab; iT < cFntTabCur; iT++, qfte++) {
|
|
if ( qfte->fAttr == pcf->fAttr &&
|
|
qfte->wIdFntName == (WORD) (pcf->wIdFntName -1) &&
|
|
qfte->bSize == pcf->bSize &&
|
|
qfte->bFntType == pcf->bFntType &&
|
|
memcmp(&qfte->bForeCol, &pcf->bForeCol, sizeof(RGBTRIPLE)) == 0 &&
|
|
memcmp(&qfte->bBackCol, &pcf->bBackCol, sizeof(RGBTRIPLE)) == 0)
|
|
return iT;
|
|
}
|
|
|
|
// Match not found, Make an entry
|
|
|
|
qfte->fAttr = pcf->fAttr;
|
|
qfte->bSize = pcf->bSize;
|
|
qfte->bFntType = pcf->bFntType;
|
|
qfte->wIdFntName = (WORD) (pcf->wIdFntName - 1);
|
|
qfte->bForeCol = pcf->bForeCol;
|
|
qfte->bBackCol = pcf->bBackCol;
|
|
|
|
// Increment the count
|
|
|
|
cFntTabCur++;
|
|
return cFntTabCur - 1;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* IGetFontSize( iInpSize )
|
|
*
|
|
* Description: Remap the font size, if we should.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
* NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
int STDCALL IGetFontSize(int iInpSize)
|
|
{
|
|
int i;
|
|
FONTRANGE *pfr;
|
|
|
|
for (i = 0, pfr = options.rgFontRange;
|
|
i < options.iFontRangeMac;
|
|
i++, pfr++) {
|
|
if (iInpSize >= pfr->halfptInMin && iInpSize <= pfr->halfptInMost) {
|
|
return pfr->halfptOut;
|
|
break;
|
|
}
|
|
}
|
|
return iInpSize;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: FProcFontId
|
|
|
|
PURPOSE: Convert a font-id into the internally-used number
|
|
|
|
PARAMETERS:
|
|
IdFontInUse
|
|
qcf
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
26-Feb-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
BOOL STDCALL FProcFontId(int IdFontInUse, CF* pcf, BOOL fSeenPtSize)
|
|
{
|
|
QIFNTENT qinpfte, qinpfteMac;
|
|
|
|
if (fSeenPtSize && !g_pFirst)
|
|
return FALSE;
|
|
|
|
if (options.pszForceFont) {
|
|
pcf->bFntType = cfDefault.bFntType;
|
|
pcf->wIdFntName = cfDefault.wIdFntName;
|
|
return TRUE;
|
|
}
|
|
|
|
if (fSeenPtSize) {
|
|
ASSERT(ptblFontNames);
|
|
char szFont[MAX4_FONTNAME + 1];
|
|
strcpy(szFont, ptblFontNames->GetPointer(pcf->wIdFntName));
|
|
int size = pcf->bSize;
|
|
int charset = paCharSets[pcf->wIdFntName - 1];
|
|
#ifdef _DEBUG
|
|
CStr cszOrgFont(szFont);
|
|
int orgSize = size;
|
|
int orgCharset = charset;
|
|
#endif
|
|
if (ReplaceFont(szFont, &size, &charset)) {
|
|
pcf->wIdFntName = GetFontNameId(szFont);
|
|
pcf->bSize = (BYTE) size;
|
|
paCharSets[pcf->wIdFntName - 1] = (BYTE) charset;
|
|
#ifdef _DEBUG
|
|
// Because VC 4 can't see structure pointers
|
|
int id = pcf->wIdFntName - 1;
|
|
#endif
|
|
|
|
if (pcf->wIdFntName > (int) idHighestUsedFont)
|
|
idHighestUsedFont = pcf->wIdFntName;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
qinpfteMac = qInpFntTab + iInpFntTabEntCount;
|
|
for (qinpfte = qInpFntTab; qinpfte < qinpfteMac; qinpfte++) {
|
|
if (qinpfte->iFntId == IdFontInUse)
|
|
break;
|
|
}
|
|
if (qinpfte < qinpfteMac) {
|
|
pcf->bFntType = qinpfte->bFntType;
|
|
pcf->wIdFntName = qinpfte->wIdFntName;
|
|
if (pcf->wIdFntName > (int) idHighestUsedFont)
|
|
idHighestUsedFont = pcf->wIdFntName;
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* IMapFontType()
|
|
*
|
|
* Description:
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
* NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
int STDCALL IMapFontType(int iTok)
|
|
{
|
|
int iFntType = 0;
|
|
|
|
switch(iTok) {
|
|
case tokFmodern:
|
|
iFntType = iModernFont;
|
|
break;
|
|
|
|
case tokFroman:
|
|
iFntType = iRomanFont;
|
|
break;
|
|
|
|
case tokFscript:
|
|
iFntType = iScriptFont;
|
|
break;
|
|
|
|
case tokFdecor:
|
|
iFntType = iDecorativeFont;
|
|
break;
|
|
|
|
default:
|
|
case tokFswiss:
|
|
iFntType = iSwissFont;
|
|
break;
|
|
}
|
|
return(iFntType);
|
|
}
|
|
|
|
void STDCALL VProcColTableInfo(CTBL* qColTab)
|
|
{
|
|
iInpColTabEntCount = qColTab->ccte;
|
|
if (qInpColTab)
|
|
lcFree(qInpColTab);
|
|
qInpColTab = (RGBTRIPLE*) lcCalloc((iInpColTabEntCount * sizeof(CTE)));
|
|
ASSERT(qInpColTab);
|
|
if (qInpColTab)
|
|
memmove(qInpColTab, qColTab->rgcte, (sizeof(CTE) *
|
|
iInpColTabEntCount));
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* VUpdateColor()
|
|
*
|
|
* Description:
|
|
* Sets the given rgb value according to the index into the
|
|
* color table. If the index exceeds the bounds of the color
|
|
* table (which will happen frequently if the color table has
|
|
* has not been initialized yet), it does nothing.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
* NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
void STDCALL VUpdateColor(RGBTRIPLE* qrgb, int iIdx)
|
|
{
|
|
if (iIdx < iInpColTabEntCount)
|
|
memcpy(qrgb, qInpColTab + iIdx, sizeof(RGBTRIPLE));
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: VOutFontTable
|
|
|
|
PURPOSE:
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
We saved all font names specified in \fonttbl -- however, this
|
|
typically specifies far more font names then are actually used.
|
|
Normally, the fonts that are actually used appear at the first
|
|
of this list, and unused ones last. We keep track of the highest
|
|
used index into our list of fonts, and only write out the ones
|
|
up to that point.
|
|
|
|
MODIFICATION DATES:
|
|
26-Feb-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
void VOutFontTable(void)
|
|
{
|
|
int iTemp;
|
|
|
|
ASSERT(ptblFontNames);
|
|
if (!ptblFontNames)
|
|
return;
|
|
|
|
LcbWriteIntAsShort(fmsg.hfFont, idHighestUsedFont);
|
|
LcbWriteIntAsShort(fmsg.hfFont, cFntTabCur);
|
|
iTemp = sizeof(INT16) * 4;
|
|
LcbWriteIntAsShort(fmsg.hfFont, iTemp);
|
|
|
|
// Write the offset to the font names
|
|
|
|
iTemp += idHighestUsedFont * MAX4_FONTNAME;
|
|
LcbWriteIntAsShort(fmsg.hfFont, iTemp);
|
|
if (!options.pszForceFont) {
|
|
for (UINT pos = 1; pos <= (UINT) idHighestUsedFont; pos++) {
|
|
char szBuf[MAX4_FONTNAME];
|
|
memset(szBuf, 0, sizeof(szBuf));
|
|
ptblFontNames->GetString(szBuf, pos);
|
|
LcbWriteHf(fmsg.hfFont, szBuf, MAX4_FONTNAME);
|
|
}
|
|
}
|
|
|
|
LcbWriteHf(fmsg.hfFont, qFntTab, sizeof(OFNTENT) * cFntTabCur);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* SetForcedFont()
|
|
*
|
|
* Description: Check that the font name specified is one we know about.
|
|
* If it isn't, force font to our default.
|
|
*
|
|
* Arguments: pszFont - font name. if unrecognized, a default font
|
|
* name is copied to this buffer
|
|
*
|
|
* Returns: NOTHING
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
void STDCALL SetForcedFont(PSTR pszFont)
|
|
{
|
|
QFT qft;
|
|
int i;
|
|
|
|
for (i = 0, qft = ftTab; i < wFTabEntryMac; qft++, i++) {
|
|
if (!_stricmp(qft->szFntName, pszFont)) {
|
|
cfDefault.bFntType = (BYTE) (qft->iFntFamily);
|
|
cfDefault.wIdFntName = 0;
|
|
return;
|
|
}
|
|
}
|
|
VReportError(HCERR_UNKNOWN_DEF_FONT, &errHpj, pszFont);
|
|
GetStringResource(IDS_DEF_FONT, pszFont);
|
|
cfDefault.bFntType = (BYTE) iSwissFont;
|
|
cfDefault.wIdFntName = 0;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: GetCharset
|
|
|
|
PURPOSE: Retrieve the charset for the specified font
|
|
|
|
PARAMETERS:
|
|
idx font index (internal number, not the RTF number)
|
|
|
|
RETURNS: charset for the specified font
|
|
|
|
COMMENTS: For version 3 help files, the charset will either be
|
|
SYMBOL_CHARSET or ANSI_CHARSET. Only version 4 help files
|
|
will use other charsets.
|
|
|
|
MODIFICATION DATES:
|
|
|
|
***************************************************************************/
|
|
|
|
BYTE STDCALL GetCharset(int idx)
|
|
{
|
|
char szBuf[MAX4_FONTNAME + 1];
|
|
|
|
if (idx == -1)
|
|
return ANSI_CHARSET; // REVIEW: valid for DBCS?
|
|
else
|
|
return(ANSI_CHARSET);
|
|
|
|
// BUGBUG: The following code is now totally useless... 21-Aug-1994 [ralphw]
|
|
|
|
ASSERT(idx <= idHighestUsedFont && idx >= 0);
|
|
ASSERT(ptblFontNames); // have we encounterd any fonts?
|
|
|
|
// And in case we make it past the above asserts...
|
|
|
|
if (idx > idHighestUsedFont || !ptblFontNames)
|
|
return ANSI_CHARSET;
|
|
|
|
idx = ((idx + 1) * 2); // because charset values are every other table entry
|
|
|
|
ptblFontNames->GetString(szBuf, idx);
|
|
return (BYTE) atoi(szBuf);
|
|
|
|
#ifdef DEADCODE
|
|
// For version 3 help files, we get the charset based on the font facename
|
|
|
|
ptblFontNames->GetString(szBuf, idx - 1);
|
|
|
|
if (stricmp("Symbol", szBuf) == 0 || stricmp("WingDings", szBuf) == 0)
|
|
return SYMBOL_CHARSET;
|
|
else {
|
|
if (defCharSet)
|
|
return defCharSet;
|
|
|
|
HDC hdc = GetDC(NULL);
|
|
|
|
// Get the system's current charset
|
|
|
|
if (hdc) {
|
|
TEXTMETRIC tm;
|
|
GetTextMetrics(hdc, &tm);
|
|
BYTE bCharSet = tm.tmCharSet;
|
|
ReleaseDC(NULL, hdc);
|
|
return bCharSet;
|
|
}
|
|
else {
|
|
return ANSI_CHARSET;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: GetFirstFont
|
|
|
|
PURPOSE: Get the first font defined
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
Called when we were handed an invalide default font number.
|
|
|
|
MODIFICATION DATES:
|
|
07-Jan-1995 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
int STDCALL GetFirstFont(void)
|
|
{
|
|
return qInpFntTab->iFntId;
|
|
}
|