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

📄 pdf_fontfilems.c.svn-base

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
#include "fitz.h"#include "mupdf.h"/* we use built-in fonts in addition to those installed on windows   because the metric for Times-Roman in windows fonts seems wrong   and we end up with over-lapping text if this font is used.   poppler doesn't have this problem even when using windows fonts   so maybe there's a better fix. */#define USE_BUILTIN_FONTS 1#ifdef USE_BUILTIN_FONTS#include "mupdf/base14.h"#endif#include <windows.h>#include <ft2build.h>#include FT_FREETYPE_H#define SAFE_FZ_READ(file, buf, size)\	err = fz_read(&byteread, (file), (char*)(buf), (size)); \	if (err) goto cleanup; \	if (byteread != (size)) err = fz_throw("ioerror");\	if (err) goto cleanup;#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])#define SWAPWORD(x)		MAKEWORD(HIBYTE(x), LOBYTE(x))#define SWAPLONG(x)		MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))#define PLATFORM_UNICODE				0#define PLATFORM_MACINTOSH				1#define PLATFORM_ISO					2#define PLATFORM_MICROSOFT				3#define UNI_ENC_UNI_1					0#define UNI_ENC_UNI_1_1					1#define UNI_ENC_ISO						2#define UNI_ENC_UNI_2_BMP				3#define UNI_ENC_UNI_2_FULL_REPERTOIRE	4#define MAC_ROMAN						0#define MAC_JAPANESE					1#define MAC_CHINESE_TRADITIONAL			2#define MAC_KOREAN						3#define MAC_CHINESE_SIMPLIFIED			25#define MS_ENC_SYMBOL					0#define MS_ENC_UNI_BMP					1#define MS_ENC_SHIFTJIS					2#define MS_ENC_PRC						3#define MS_ENC_BIG5						4#define MS_ENC_WANSUNG					5#define MS_ENC_JOHAB					6#define MS_ENC_UNI_FULL_REPETOIRE		10#define TTC_VERSION1	0x00010000#define TTC_VERSION2	0x00020000typedef struct pdf_fontmapMS_s pdf_fontmapMS;typedef struct pdf_fontlistMS_s pdf_fontlistMS;struct pdf_fontmapMS_s{	char fontface[128];	char fontpath[MAX_PATH+1];	int index;};struct pdf_fontlistMS_s{	pdf_fontmapMS *fontmap;	int len;	int cap;};typedef struct _tagTT_OFFSET_TABLE{	USHORT	uMajorVersion;	USHORT	uMinorVersion;	USHORT	uNumOfTables;	USHORT	uSearchRange;	USHORT	uEntrySelector;	USHORT	uRangeShift;} TT_OFFSET_TABLE;typedef struct _tagTT_TABLE_DIRECTORY{	char	szTag[4];			//table name	ULONG	uCheckSum;			//Check sum	ULONG	uOffset;			//Offset from beginning of file	ULONG	uLength;			//length of the table in bytes} TT_TABLE_DIRECTORY;typedef struct _tagTT_NAME_TABLE_HEADER{	USHORT	uFSelector;			//format selector. Always 0	USHORT	uNRCount;			//Name Records count	USHORT	uStorageOffset;		//Offset for strings storage, from start of the table} TT_NAME_TABLE_HEADER;typedef struct _tagTT_NAME_RECORD{	USHORT	uPlatformID;	USHORT	uEncodingID;	USHORT	uLanguageID;	USHORT	uNameID;	USHORT	uStringLength;	USHORT	uStringOffset;	//from start of storage area} TT_NAME_RECORD;typedef struct _tagFONT_COLLECTION{	char	Tag[4];	ULONG	Version;	ULONG	NumFonts;}FONT_COLLECTION;static char *basenames[13] ={	"Courier",	"Courier-Bold",	"Courier-Oblique",	"Courier-BoldOblique",	"Helvetica",	"Helvetica-Bold",	"Helvetica-Oblique",	"Helvetica-BoldOblique",	"Times-Roman",	"Times-Bold",	"Times-Italic",	"Times-BoldItalic",	"Symbol",};static char *basepatterns[13] ={	"CourierNewPSMT",	"CourierNewPS-BoldMT",	"CourierNewPS-ItalicMT",	"CourierNewPS-BoldItalicMT",	"ArialMT",	"Arial-BoldMT",	"Arial-ItalicMT",	"Arial-BoldItalicMT",	"TimesNewRomanPSMT",	"TimesNewRomanPS-BoldMT",	"TimesNewRomanPS-ItalicMT",	"TimesNewRomanPS-BoldItalicMT",	"SymbolMT"};static pdf_fontlistMS fontlistMS ={	NULL,	0,	0,};struct pdf_fontmapMS_s defaultSubstitute;enum{	FD_FIXED = 1 << 0,	FD_SERIF = 1 << 1,	FD_SYMBOLIC = 1 << 2,	FD_SCRIPT = 1 << 3,	FD_NONSYMBOLIC = 1 << 5,	FD_ITALIC = 1 << 6,	FD_ALLCAP = 1 << 16,	FD_SMALLCAP = 1 << 17,	FD_FORCEBOLD = 1 << 18};/* A little bit more sophisticated name matching so that e.g. "EurostileExtended"   matches "EurostileExtended-Roman" */static intfontnamematches(const char *s1, const char *s2){	const char *rest;	int c1, c2;	while (*s1 && *s2)	{		c1 = tolower(*s1++);		c2 = tolower(*s2++);		if (c1 != c2)			return 0;	}	if (!*s1 && !*s2)		return 1;	rest = s2;	if (*s1)		rest = s1;	if (0 == stricmp(rest, "-roman"))		return 1;	return 0;}static intlookupcompare(const void *elem1, const void *elem2){	pdf_fontmapMS *val1 = (pdf_fontmapMS *)elem1;	pdf_fontmapMS *val2 = (pdf_fontmapMS *)elem2;	if (val1->fontface[0] == 0)		return 1;	if (val2->fontface[0] == 0)		return -1;	if (fontnamematches(val1->fontface, val2->fontface))		return 0;	return stricmp(val1->fontface, val2->fontface);}static intsortcompare(const void *elem1, const void *elem2){	pdf_fontmapMS *val1 = (pdf_fontmapMS *)elem1;	pdf_fontmapMS *val2 = (pdf_fontmapMS *)elem2;	if (val1->fontface[0] == 0)		return 1;	if (val2->fontface[0] == 0)		return -1;	return stricmp(val1->fontface, val2->fontface);}static void *localbsearch (const void *key, const void *base, size_t num,		 size_t width, int (*compare)(const void *, const void *)){	char *lo = (char *)base;	char *hi = (char *)base + (num - 1) * width;	char *mid;	unsigned int half;	int result;	while (lo <= hi)		if (half = num / 2)		{			mid = lo + (num & 1 ? half : (half - 1)) * width;			if (!(result = (*compare)(key,mid)))				return(mid);			else if (result < 0)			{				hi = mid - width;				num = num & 1 ? half : half-1;			}			else	{				lo = mid + width;				num = half;			}		}		else if (num)			return((*compare)(key,lo) ? 0 : lo);		else			break;		return(0);}static voidremoveredundancy(pdf_fontlistMS *fl){	int i;	int roffset = 0;	int redundancy_count = 0;	qsort(fl->fontmap, fl->len, sizeof(pdf_fontmapMS), sortcompare);	for (i = 0; i < fl->len - 1; ++i)	{		if (strcmp(fl->fontmap[i].fontface,fl->fontmap[i+1].fontface) == 0)		{			fl->fontmap[i].fontface[0] = 0;			++redundancy_count;		}	}	qsort(fl->fontmap, fl->len, sizeof(pdf_fontmapMS), sortcompare);	fl->len -= redundancy_count;#if 0	for (i = 0; i < fl->len; ++i)		fprintf(stdout,"%s , %s , %d\n",fl->fontmap[i].fontface,			fl->fontmap[i].fontpath,fl->fontmap[i].index);#endif}static voidfinddefaultsubstitutes(pdf_fontlistMS *fl){	int i;	for (i = 0; i < fl->len; ++i)	{		char *face = fl->fontmap[i].fontface;#if defined(_MSC_VER) && 0		OutputDebugStringA(face);		OutputDebugStringA("\n");#endif		if (0 == strcmp(face, "TimesNewRomanPSMT"))		{			defaultSubstitute = fl->fontmap[i];		}	}}static fz_error *swapword(char* pbyte, int nLen){	int i;	char tmp;	int nMax;	if (nLen % 2)		return fz_throw("fonterror");	nMax = nLen / 2;	for (i = 0; i < nLen; ++i) {		tmp = pbyte[i*2];		pbyte[i*2] = pbyte[i*2+1];		pbyte[i*2+1] = tmp;	}	return 0;}/* pSouce and PDest can be same */static fz_error *decodeunicodeBMP(char* source, int sourcelen,char* dest, int destlen){	wchar_t tmp[1024*2];	int converted;	memset(tmp,0,sizeof(tmp));	memcpy(tmp,source,sourcelen);	swapword((char*)tmp,sourcelen);	converted = WideCharToMultiByte(CP_ACP, 0, tmp,		-1, dest, destlen, NULL, NULL);	if (converted == 0)		return fz_throw("fonterror");	return 0;}static fz_error *decodeunicodeplatform(char* source, int sourcelen,char* dest, int destlen, int enctype){	fz_error *err = nil;	switch(enctype)	{	case UNI_ENC_UNI_1:	case UNI_ENC_UNI_2_BMP:		err = decodeunicodeBMP(source,sourcelen,dest,destlen);		break;	case UNI_ENC_UNI_2_FULL_REPERTOIRE:	case UNI_ENC_UNI_1_1:	case UNI_ENC_ISO:	default:		err = fz_throw("fonterror : unsupported encoding");		break;	}	return err;}static fz_error *decodemacintoshplatform(char* source, int sourcelen,char* dest, int destlen, int enctype){	fz_error *err = nil;	switch(enctype)	{	case MAC_ROMAN:		if (sourcelen + 1 > destlen)			err = fz_throw("fonterror : short buf lenth");		else		{			memcpy(source,dest,sourcelen);			dest[sourcelen] = 0;		}		break;	default:		err = fz_throw("fonterror : unsupported encoding");		break;	}	return err;}static fz_error *decodemicrosoftplatform(char* source, int sourcelen,char* dest, int destlen, int enctype){	fz_error *err = nil;	switch(enctype)	{	case MS_ENC_SYMBOL:	case MS_ENC_UNI_BMP:	case MS_ENC_UNI_FULL_REPETOIRE:		err = decodeunicodeBMP(source,sourcelen,dest,destlen);		break;	default:		err = fz_throw("fonterror : unsupported encoding");		break;	}	return err;}static fz_error *growfontlist(pdf_fontlistMS *fl){	int newcap;	pdf_fontmapMS *newitems;	if (fl->cap == 0)		newcap = 1024;	else		newcap = fl->cap * 2;	newitems = fz_realloc(fl->fontmap, sizeof(pdf_fontmapMS) * newcap);	if (!newitems)		return fz_outofmem;	memset(newitems + fl->cap, 0,		sizeof(struct fz_keyval_s) * (newcap - fl->cap));	fl->fontmap = newitems;	fl->cap = newcap;	return fz_okay;}static fz_error *insertmapping(pdf_fontlistMS *fl, char *facename, char *path, int index){	fz_error *err;	if (fl->len == fl->cap) {		err = growfontlist(fl);		if (err) return err;	}	if (fl->len >= fl->cap)		return fz_throw("fonterror : fontlist overflow");	strlcpy(fl->fontmap[fl->len].fontface, facename,		sizeof(fl->fontmap[0].fontface));	strlcpy(fl->fontmap[fl->len].fontpath, path,		sizeof(fl->fontmap[0].fontpath));	fl->fontmap[fl->len].index = index;	++fl->len;	return fz_okay;}static fz_error *parseTTF(fz_stream *file, int offset, int index, char *path){	fz_error *err = nil;	int byteread;	TT_OFFSET_TABLE ttOffsetTable;	TT_TABLE_DIRECTORY tblDir;	TT_NAME_TABLE_HEADER ttNTHeader;	TT_NAME_RECORD ttRecord;	char szTemp[4096];	int found;	int i;	fz_seek(file,offset,0);	SAFE_FZ_READ(file, &ttOffsetTable, sizeof(TT_OFFSET_TABLE));	ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);	ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);	ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);	//check is this is a true type font and the version is 1.0	if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)		return fz_throw("fonterror : invalid font version");	found = 0;	for (i = 0; i< ttOffsetTable.uNumOfTables; i++)	{		SAFE_FZ_READ(file,&tblDir,sizeof(TT_TABLE_DIRECTORY));		memcpy(szTemp, tblDir.szTag, 4);		szTemp[4] = 0;		if (stricmp(szTemp, "name") == 0)		{			found = 1;			tblDir.uLength = SWAPLONG(tblDir.uLength);			tblDir.uOffset = SWAPLONG(tblDir.uOffset);			break;		}		else if (szTemp[0] == 0)		{			break;		}	}	if (found)	{		fz_seek(file,tblDir.uOffset,0);		SAFE_FZ_READ(file,&ttNTHeader,sizeof(TT_NAME_TABLE_HEADER));		ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);		ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);		offset = tblDir.uOffset + sizeof(TT_NAME_TABLE_HEADER);		for (i = 0; i < ttNTHeader.uNRCount && err == nil; ++i)		{			fz_seek(file, offset + sizeof(TT_NAME_RECORD)*i, 0);			SAFE_FZ_READ(file,&ttRecord,sizeof(TT_NAME_RECORD));

⌨️ 快捷键说明

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