⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fonts.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * fonts.c * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL * * Description: * Functions to deal with fonts (generic) */#include <ctype.h>#include <string.h>#include "antiword.h"/* Maximum line length in the font file */#define FONT_LINE_LENGTH	81/* Pitch */#define PITCH_UNKNOWN		0#define PITCH_FIXED		1#define PITCH_VARIABLE		2/* Font Family */#define FAMILY_UNKNOWN		0#define FAMILY_ROMAN		1#define FAMILY_SWISS		2#define FAMILY_MODERN		3#define FAMILY_SCRIPT		4#define FAMILY_DECORATIVE	5/* Font Translation Table */static size_t		tFontTableRecords = 0;static font_table_type	*pFontTable = NULL;/* * Find the given font in the font table * * returns the index into the FontTable, -1 if not found */intiGetFontByNumber(UCHAR ucWordFontNumber, USHORT usFontStyle){	int	iIndex;	for (iIndex = 0; iIndex < (int)tFontTableRecords; iIndex++) {		if (ucWordFontNumber == pFontTable[iIndex].ucWordFontNumber &&		    usFontStyle == pFontTable[iIndex].usFontStyle &&		    pFontTable[iIndex].szOurFontname[0] != '\0') {			return iIndex;		}	}	DBG_DEC(ucWordFontNumber);	DBG_HEX(usFontStyle);	return -1;} /* end of iGetFontByNumber *//* * szGetOurFontname - Get our font name * * return our font name from the given index, NULL if not found */const char *szGetOurFontname(int iIndex){	if (iIndex < 0 || iIndex >= (int)tFontTableRecords) {		return NULL;	}	return pFontTable[iIndex].szOurFontname;} /* end of szGetOurFontname *//* * Find the given font in the font table * * returns the Word font number, -1 if not found */intiFontname2Fontnumber(const char *szOurFontname, USHORT usFontStyle){	int	iIndex;	for (iIndex = 0; iIndex < (int)tFontTableRecords; iIndex++) {		if (pFontTable[iIndex].usFontStyle == usFontStyle &&		    STREQ(pFontTable[iIndex].szOurFontname, szOurFontname)) {			return (int)pFontTable[iIndex].ucWordFontNumber;		}	}	return -1;} /* end of iFontname2Fontnumber *//* * szGetDefaultFont - get the default font that matches the parameters */static const char *szGetDefaultFont(UCHAR ucFFN, int iEmphasis){	UCHAR	ucPrq, ucFf;	fail(iEmphasis < 0 || iEmphasis > 3);	ucPrq = ucFFN & 0x03;	ucFf = (ucFFN & 0x70) >> 4;	NO_DBG_DEC(ucPrq);	NO_DBG_DEC(ucFf);	if (ucPrq == PITCH_FIXED) {		/* Set to the default monospaced font */		switch (iEmphasis) {		case 1: return FONT_MONOSPACED_BOLD;		case 2: return FONT_MONOSPACED_ITALIC;		case 3: return FONT_MONOSPACED_BOLDITALIC;		default: return FONT_MONOSPACED_PLAIN;		}	} else if (ucFf == FAMILY_ROMAN) {		/* Set to the default serif font */		switch (iEmphasis) {		case 1: return FONT_SERIF_BOLD;		case 2: return FONT_SERIF_ITALIC;		case 3: return FONT_SERIF_BOLDITALIC;		default: return FONT_SERIF_PLAIN;		}	} else if (ucFf == FAMILY_SWISS) {		/* Set to the default sans serif font */		switch (iEmphasis) {		case 1: return FONT_SANS_SERIF_BOLD;		case 2: return FONT_SANS_SERIF_ITALIC;		case 3: return FONT_SANS_SERIF_BOLDITALIC;		default: return FONT_SANS_SERIF_PLAIN;		}	} else {		/* Set to the default default font */		switch (iEmphasis) {		case 1: return FONT_SERIF_BOLD;		case 2: return FONT_SERIF_ITALIC;		case 3: return FONT_SERIF_BOLDITALIC;		default: return FONT_SERIF_PLAIN;		}	}} /* end of szGetDefaultFont *//* * See if the fontname from the Word file matches the fontname from the * font translation file. * If iBytesPerChar is one than aucWord is in ISO-8859-x (Word 2/6/7), * if iBytesPerChar is two than aucWord is in Unicode (Word 8/9/10). */static BOOLbFontEqual(const UCHAR *aucWord, const char *szTable, int iBytesPerChar){	const UCHAR	*pucTmp;	const char	*pcTmp;	fail(aucWord == NULL || szTable == NULL);	fail(iBytesPerChar != 1 && iBytesPerChar != 2);	for (pucTmp = aucWord, pcTmp = szTable;	     *pucTmp != 0;	     pucTmp += iBytesPerChar, pcTmp++) {		if (ulToUpper((ULONG)*pucTmp) !=		    ulToUpper((ULONG)(UCHAR)*pcTmp)) {			return FALSE;		}	}	return *pcTmp == '\0';} /* end of bFontEqual *//* * vFontname2Table - add fontnames to the font table */static voidvFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont,	int iBytesPerChar, int iEmphasis, UCHAR ucFFN,	const char *szWordFont, const char *szOurFont,	font_table_type *pFontTableRecord){	BOOL	bMatchFound;	fail(aucFont == NULL || aucFont[0] == 0);	fail(aucAltFont != NULL && aucAltFont[0] == 0);	fail(iBytesPerChar != 1 && iBytesPerChar != 2);	fail(iEmphasis < 0 || iEmphasis > 3);	fail(szWordFont == NULL || szWordFont[0] == '\0');	fail(szOurFont == NULL || szOurFont[0] == '\0');	fail(pFontTableRecord == NULL);	bMatchFound = bFontEqual(aucFont, szWordFont, iBytesPerChar);	if (!bMatchFound && aucAltFont != NULL) {		bMatchFound = bFontEqual(aucAltFont, szWordFont, iBytesPerChar);	}	if (!bMatchFound &&	    pFontTableRecord->szWordFontname[0] == '\0' &&	    szWordFont[0] == '*' &&	    szWordFont[1] == '\0') {		/*		 * szWordFont contains a "*", so szOurFont will contain the		 * "default default" font. See if we can do better than that.		 */		szOurFont = szGetDefaultFont(ucFFN, iEmphasis);		bMatchFound = TRUE;	}	if (bMatchFound) {		switch (iBytesPerChar) {		case 1:			(void)strncpy(pFontTableRecord->szWordFontname,				(const char *)aucFont,				sizeof(pFontTableRecord->szWordFontname) - 1);			break;		case 2:			(void)unincpy(pFontTableRecord->szWordFontname,				aucFont,				sizeof(pFontTableRecord->szWordFontname) - 1);			break;		default:			DBG_FIXME();			pFontTableRecord->szWordFontname[0] = '\0';			break;		}		pFontTableRecord->szWordFontname[			sizeof(pFontTableRecord->szWordFontname) - 1] = '\0';		(void)strncpy(pFontTableRecord->szOurFontname, szOurFont,			sizeof(pFontTableRecord->szOurFontname) - 1);		pFontTableRecord->szOurFontname[			sizeof(pFontTableRecord->szOurFontname) - 1] = '\0';		NO_DBG_MSG(pFontTableRecord->szWordFontname);		NO_DBG_MSG(pFontTableRecord->szOurFontname);		pFontTableRecord->ucFFN = ucFFN;		pFontTableRecord->ucEmphasis = (UCHAR)iEmphasis;	}} /* end of vFontname2Table *//* * vCreateFontTable - Create and initialize the internal font table */static voidvCreateFontTable(void){	font_table_type	*pTmp;	int	iNbr;	if (tFontTableRecords == 0) {		pFontTable = xfree(pFontTable);		return;	}	/* Create the font table */	pFontTable = xcalloc(tFontTableRecords, sizeof(*pFontTable));	/* Initialize the font table */	for (iNbr = 0, pTmp = pFontTable;	     pTmp < pFontTable + tFontTableRecords;	     iNbr++, pTmp++) {		pTmp->ucWordFontNumber = (UCHAR)(iNbr / 4);		switch (iNbr % 4) {		case 0:			pTmp->usFontStyle = FONT_REGULAR;			break;		case 1:			pTmp->usFontStyle = FONT_BOLD;			break;		case 2:			pTmp->usFontStyle = FONT_ITALIC;			break;		case 3:			pTmp->usFontStyle = FONT_BOLD|FONT_ITALIC;			break;		default:			DBG_DEC(iNbr);			break;		}	}} /* end of vCreateFontTable *//* * vMinimizeFontTable - make the font table as small as possible */static voidvMinimizeFontTable(void){	font_block_type		tFontNext;	const style_block_type	*pStyle;	const font_block_type	*pFont;	font_table_type		*pTmp;	int	iUnUsed;	BOOL	bMustAddTableFont;	NO_DBG_MSG("vMinimizeFontTable");	if (tFontTableRecords == 0) {		pFontTable = xfree(pFontTable);		return;	}	/* See if we must add a font for our tables */	bMustAddTableFont = TRUE;#if 0	DBG_MSG("Before");	DBG_DEC(tFontTableRecords);	for (pTmp = pFontTable;	     pTmp < pFontTable + tFontTableRecords;	     pTmp++) {		DBG_DEC(pTmp->ucWordFontNumber);		DBG_HEX(pTmp->usFontStyle);		DBG_MSG(pTmp->szWordFontname);		DBG_MSG(pTmp->szOurFontname);	}#endif /* DEBUG */	/* See which fonts/styles we really need */	/* Default font/style is by definition in use */	pFontTable[0].ucInUse = 1;	/* Make InUse 1 for all the fonts/styles that WILL be used */	pFont = NULL;	while((pFont = pGetNextFontInfoListItem(pFont)) != NULL) {		pTmp = pFontTable + 4 * (int)pFont->ucFontNumber;		if (bIsBold(pFont->usFontStyle)) {			pTmp++;		}		if (bIsItalic(pFont->usFontStyle)) {			pTmp += 2;		}		if (pTmp >= pFontTable + tFontTableRecords) {			continue;		}		if (STREQ(pTmp->szOurFontname, TABLE_FONT)) {			/* The table font is already present */			bMustAddTableFont = FALSE;		}		pTmp->ucInUse = 1;	}	/* Make InUse 1 for all the fonts/styles that MIGHT be used */	pStyle = NULL;	while((pStyle = pGetNextStyleInfoListItem(pStyle)) != NULL) {		vFillFontFromStylesheet(pStyle->usIstdNext, &tFontNext);		vCorrectFontValues(&tFontNext);		pTmp = pFontTable + 4 * (int)tFontNext.ucFontNumber;		if (bIsBold(tFontNext.usFontStyle)) {			pTmp++;		}		if (bIsItalic(tFontNext.usFontStyle)) {			pTmp += 2;		}		if (pTmp >= pFontTable + tFontTableRecords) {			continue;		}		if (STREQ(pTmp->szOurFontname, TABLE_FONT)) {			/* The table font is already present */			bMustAddTableFont = FALSE;		}		pTmp->ucInUse = 1;	}	/* Remove the unused font entries from the font table */	iUnUsed = 0;	for (pTmp = pFontTable;	     pTmp < pFontTable + tFontTableRecords;	     pTmp++) {		if (pTmp->ucInUse == 0) {			iUnUsed++;			continue;		}		if (iUnUsed > 0) {			fail(pTmp - iUnUsed <= pFontTable);			*(pTmp - iUnUsed) = *pTmp;		}	}	fail(iUnUsed < 0);	fail(tFontTableRecords <= (size_t)iUnUsed);	tFontTableRecords -= (size_t)iUnUsed;	if (bMustAddTableFont) {		pTmp = pFontTable + tFontTableRecords;		fail(pTmp <= pFontTable);		pTmp->ucWordFontNumber = (pTmp - 1)->ucWordFontNumber + 1;		pTmp->usFontStyle = FONT_REGULAR;		pTmp->ucInUse = 1;		strcpy(pTmp->szWordFontname, "Extra Table Font");		strcpy(pTmp->szOurFontname, TABLE_FONT);		tFontTableRecords++;		iUnUsed--;	}	if (iUnUsed > 0) {		/* Resize the font table */		pFontTable = xrealloc(pFontTable,				tFontTableRecords * sizeof(*pFontTable));	}#if defined(DEBUG)	DBG_MSG("After");	DBG_DEC(tFontTableRecords);	for (pTmp = pFontTable;	     pTmp < pFontTable + tFontTableRecords;	     pTmp++) {		DBG_DEC(pTmp->ucWordFontNumber);		DBG_HEX(pTmp->usFontStyle);		DBG_MSG(pTmp->szWordFontname);		DBG_MSG(pTmp->szOurFontname);	}#endif /* DEBUG */} /* end of vMinimizeFontTable *//* * bReadFontFile - read and check a line from the font translation file * * returns TRUE when a correct line has been read, otherwise FALSE */static BOOLbReadFontFile(FILE *pFontTableFile, char *szWordFont,	int *piItalic, int *piBold, char *szOurFont, int *piSpecial){	char	*pcTmp;	int	iFields;	char	szLine[FONT_LINE_LENGTH];	fail(szWordFont == NULL || szOurFont == NULL);	fail(piItalic == NULL || piBold == NULL || piSpecial == NULL);	while (fgets(szLine, (int)sizeof(szLine), pFontTableFile) != NULL) {		if (szLine[0] == '#' ||		    szLine[0] == '\n' ||		    szLine[0] == '\r') {			continue;		}		iFields = sscanf(szLine, "%[^,],%d,%d,%1s%[^,],%d",			szWordFont, piItalic, piBold,			&szOurFont[0], &szOurFont[1], piSpecial);		if (iFields != 6) {			pcTmp = strchr(szLine, '\r');			if (pcTmp != NULL) {				*pcTmp = '\0';			}			pcTmp = strchr(szLine, '\n');			if (pcTmp != NULL) {				*pcTmp = '\0';			}			DBG_DEC(iFields);			werr(0, "Syntax error in: '%s'", szLine);			continue;		}		if (strlen(szWordFont) >=				sizeof(pFontTable[0].szWordFontname)) {			werr(0, "Word fontname too long: '%s'", szWordFont);			continue;		}		if (strlen(szOurFont) >=				sizeof(pFontTable[0].szOurFontname)) {			werr(0, "Local fontname too long: '%s'", szOurFont);			continue;		}		/* The current line passed all the tests */		return TRUE;	}	return FALSE;} /* end of bReadFontFile *//* * vCreate0FontTable - create a font table from Word for DOS */voidvCreate0FontTable(void){	FILE	*pFontTableFile;	font_table_type	*pTmp;	UCHAR	*aucFont;	int	iBold, iItalic, iSpecial, iEmphasis, iFtc;	UCHAR	ucPrq, ucFf, ucFFN;	char	szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH];	tFontTableRecords = 0;	pFontTable = xfree(pFontTable);	pFontTableFile = pOpenFontTableFile();	if (pFontTableFile == NULL) {		/* No translation table file, no translation table */		return;	}	/* Get the maximum number of entries in the font table */	tFontTableRecords = 64;	tFontTableRecords *= 4;	/* Plain, Bold, Italic and Bold/italic */	tFontTableRecords++;	/* One extra for the table-font */	vCreateFontTable();	/* Read the font translation file */	iItalic = 0;	iBold = 0;	iSpecial = 0;	while (bReadFontFile(pFontTableFile, szWordFont,			&iItalic, &iBold, szOurFont, &iSpecial)) {		iEmphasis = 0;		if (iBold != 0) {			iEmphasis++;		}		if (iItalic != 0) {			iEmphasis += 2;		}		for (iFtc = 0, pTmp = pFontTable + iEmphasis;		     pTmp < pFontTable + tFontTableRecords;		     iFtc++, pTmp += 4) {			if (iFtc >= 16 && iFtc <= 55) {				ucPrq = PITCH_VARIABLE;				ucFf = FAMILY_ROMAN;				aucFont = (UCHAR *)"Times";			} else {				ucPrq = PITCH_FIXED;				ucFf = FAMILY_MODERN;				aucFont = (UCHAR *)"Courier";			}			ucFFN = (ucFf << 4) | ucPrq;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -