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

📄 pdf_font.c.svn-base

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
					{						int j;						/* TODO: this is horribly slow */						for (j = 0; j < 256; j++)						{							if (ebuffer[j][0] && !strcmp(s, ebuffer[j]))							{								etable[i] = j;								break;							}						}					}					/* TODO: should this really be here? */					if (ebuffer[i][0])						estrings[i] = ebuffer[i];				}			}		}		fz_dropobj(encoding);	}	else	{		pdf_logfont("encode builtin\n");		for (i = 0; i < 256; i++)		{			etable[i] = ftcharindex(face, i);			FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32);			if (ebuffer[i][0])				estrings[i] = ebuffer[i];		}	}	error = pdf_newidentitycmap(&font->encoding, 0, 1);	if (error)		goto cleanup;	font->ncidtogid = 256;	font->cidtogid = etable;	error = pdf_loadtounicode(font, xref,			estrings, nil, fz_dictgets(dict, "ToUnicode"));	if (error)		goto cleanup;	/*	 * Widths	 */	fz_setdefaulthmtx((fz_font*)font, font->missingwidth);	widths = fz_dictgets(dict, "Widths");	if (widths)	{		int first, last;		error = pdf_resolve(&widths, xref);		if (error)			goto cleanup;		first = fz_toint(fz_dictgets(dict, "FirstChar"));		last = fz_toint(fz_dictgets(dict, "LastChar"));		if (first < 0 || last > 255 || first > last)			first = last = 0;		for (i = 0; i < last - first + 1; i++)		{			int wid = fz_toint(fz_arrayget(widths, i));			error = fz_addhmtx((fz_font*)font, i + first, i + first, wid);			if (error)				goto cleanup;		}		fz_dropobj(widths);	}	else	{		FT_Set_Char_Size(face, 1000, 1000, 72, 72);		for (i = 0; i < 256; i++)		{			error = fz_addhmtx((fz_font*)font, i, i, ftwidth(font, i));			if (error)				goto cleanup;		}	}	error = fz_endhmtx((fz_font*)font);	if (error)		goto cleanup;	pdf_logfont("}\n");	*fontp = font;	return fz_okay;cleanup:	fz_free(etable);	if (widths)		fz_dropobj(widths);	fz_dropfont((fz_font*)font);	return fz_rethrow(error, "cannot load simple font");}/* * CID Fonts */static fz_error *loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj *encoding, fz_obj *tounicode){	fz_error *error;	fz_obj *widths = nil;	fz_obj *descriptor;	pdf_font *font;	FT_Face face;	fz_irect bbox;	int kind;	char collection[256];	char *basefont;	int i, k;	/*	 * Get font name and CID collection	 */	basefont = fz_toname(fz_dictgets(dict, "BaseFont"));	{		fz_obj *cidinfo;		fz_obj *obj;		char tmpstr[64];		int tmplen;		cidinfo = fz_dictgets(dict, "CIDSystemInfo");		error = pdf_resolve(&cidinfo, xref);		if (error)			return fz_rethrow(error, "cannot find CIDSystemInfo");		obj = fz_dictgets(cidinfo, "Registry");		tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj));		memcpy(tmpstr, fz_tostrbuf(obj), tmplen);		tmpstr[tmplen] = '\0';		strlcpy(collection, tmpstr, sizeof collection);		strlcat(collection, "-", sizeof collection);		obj = fz_dictgets(cidinfo, "Ordering");		tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj));		memcpy(tmpstr, fz_tostrbuf(obj), tmplen);		tmpstr[tmplen] = '\0';		strlcat(collection, tmpstr, sizeof collection);		fz_dropobj(cidinfo);	}	/*	 * Load font file	 */	font = pdf_newfont(basefont);	if (!font)		return fz_outofmem;	pdf_logfont("load cid font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), font);	pdf_logfont("basefont %s\n", basefont);	pdf_logfont("collection %s\n", collection);	descriptor = fz_dictgets(dict, "FontDescriptor");	if (descriptor)		error = pdf_loadfontdescriptor(font, xref, descriptor, collection);	else		error = fz_throw("syntaxerror: missing font descriptor");	if (error)		goto cleanup;	face = font->ftface;	kind = ftkind(face);	bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM;	bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM;	bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM;	bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM;	pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1);	if (bbox.x0 == bbox.x1)		fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000);	else		fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);	/*	 * Encoding	 */	if (fz_isname(encoding))	{		pdf_logfont("encoding /%s\n", fz_toname(encoding));		if (!strcmp(fz_toname(encoding), "Identity-H"))			error = pdf_newidentitycmap(&font->encoding, 0, 2);		else if (!strcmp(fz_toname(encoding), "Identity-V"))			error = pdf_newidentitycmap(&font->encoding, 1, 2);		else			error = pdf_loadsystemcmap(&font->encoding, fz_toname(encoding));	}	else if (fz_isindirect(encoding))	{		pdf_logfont("encoding %d %d R\n", fz_tonum(encoding), fz_togen(encoding));		error = pdf_loadembeddedcmap(&font->encoding, xref, encoding);	}	else	{		error = fz_throw("syntaxerror: font missing encoding");	}	if (error)		goto cleanup;	fz_setfontwmode((fz_font*)font, pdf_getwmode(font->encoding));	pdf_logfont("wmode %d\n", pdf_getwmode(font->encoding));	if (kind == TRUETYPE)	{		fz_obj *cidtogidmap;		cidtogidmap = fz_dictgets(dict, "CIDToGIDMap");		if (fz_isindirect(cidtogidmap))		{			unsigned short *map;			fz_buffer *buf;			int len;			pdf_logfont("cidtogidmap stream\n");			error = pdf_loadstream(&buf, xref, fz_tonum(cidtogidmap), fz_togen(cidtogidmap));			if (error)				goto cleanup;			len = (buf->wp - buf->rp) / 2;			map = fz_malloc(len * sizeof(unsigned short));			if (!map) {				fz_dropbuffer(buf);				error = fz_outofmem;				goto cleanup;			}			for (i = 0; i < len; i++)				map[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1];			font->ncidtogid = len;			font->cidtogid = map;			fz_dropbuffer(buf);		}		/* if truetype font is external, cidtogidmap should not be identity */		/* so we map from cid to unicode and then map that through the (3 1) */		/* unicode cmap to get a glyph id */		else if (font->substitute)		{			int e;			pdf_logfont("emulate ttf cidfont\n");			e = FT_Select_Charmap(face, ft_encoding_unicode);			if (e)				return fz_throw("fonterror: no unicode cmap when emulating CID font");			if (!strcmp(collection, "Adobe-CNS1"))				error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-CNS1-UCS2");			else if (!strcmp(collection, "Adobe-GB1"))				error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-GB1-UCS2");			else if (!strcmp(collection, "Adobe-Japan1"))				error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Japan1-UCS2");			else if (!strcmp(collection, "Adobe-Japan2"))				error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Japan2-UCS2");			else if (!strcmp(collection, "Adobe-Korea1"))				error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Korea1-UCS2");			else				error = fz_okay;			if (error)				return fz_rethrow(error, "cannot load system cmap %s", collection);		}	}	error = pdf_loadtounicode(font, xref, nil, collection, tounicode);	if (error)		goto cleanup;	/*	 * Horizontal	 */	fz_setdefaulthmtx((fz_font*)font, fz_toint(fz_dictgets(dict, "DW")));	widths = fz_dictgets(dict, "W");	if (widths)	{		int c0, c1, w;		fz_obj *obj;		error = pdf_resolve(&widths, xref);		if (error)			goto cleanup;		for (i = 0; i < fz_arraylen(widths); )		{			c0 = fz_toint(fz_arrayget(widths, i));			obj = fz_arrayget(widths, i + 1);			if (fz_isarray(obj))			{				for (k = 0; k < fz_arraylen(obj); k++)				{					w = fz_toint(fz_arrayget(obj, k));					error = fz_addhmtx((fz_font*)font, c0 + k, c0 + k, w);					if (error)						goto cleanup;				}				i += 2;			}			else			{				c1 = fz_toint(obj);				w = fz_toint(fz_arrayget(widths, i + 2));				error = fz_addhmtx((fz_font*)font, c0, c1, w);				if (error)					goto cleanup;				i += 3;			}		}		fz_dropobj(widths);	}	error = fz_endhmtx((fz_font*)font);	if (error)		goto cleanup;	/*	 * Vertical	 */	if (pdf_getwmode(font->encoding) == 1)	{		fz_obj *obj;		int dw2y = 880;		int dw2w = -1000;		obj = fz_dictgets(dict, "DW2");		if (obj)		{			dw2y = fz_toint(fz_arrayget(obj, 0));			dw2w = fz_toint(fz_arrayget(obj, 1));		}		fz_setdefaultvmtx((fz_font*)font, dw2y, dw2w);		widths = fz_dictgets(dict, "W2");		if (widths)		{			int c0, c1, w, x, y, k;			error = pdf_resolve(&widths, xref);			if (error)				goto cleanup;			for (i = 0; i < fz_arraylen(widths); )			{				c0 = fz_toint(fz_arrayget(widths, i));				obj = fz_arrayget(widths, i + 1);				if (fz_isarray(obj))				{					for (k = 0; k < fz_arraylen(obj); k += 3)					{						w = fz_toint(fz_arrayget(obj, k + 0));						x = fz_toint(fz_arrayget(obj, k + 1));						y = fz_toint(fz_arrayget(obj, k + 2));						error = fz_addvmtx((fz_font*)font, c0 + k, c0 + k, x, y, w);						if (error)							goto cleanup;					}					i += 2;				}				else				{					c1 = fz_toint(obj);					w = fz_toint(fz_arrayget(widths, i + 2));					x = fz_toint(fz_arrayget(widths, i + 3));					y = fz_toint(fz_arrayget(widths, i + 4));					error = fz_addvmtx((fz_font*)font, c0, c1, x, y, w);					if (error)						goto cleanup;					i += 5;				}			}			fz_dropobj(widths);		}		error = fz_endvmtx((fz_font*)font);		if (error)			goto cleanup;	}	pdf_logfont("}\n");	*fontp = font;	return fz_okay;cleanup:	if (widths)		fz_dropobj(widths);	fz_dropfont((fz_font*)font);	return fz_rethrow(error, "cannot load cid font");}static fz_error *loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref){	fz_error *error;	fz_obj *dfonts;	fz_obj *dfont;	fz_obj *subtype;	fz_obj *encoding;	fz_obj *tounicode;	dfonts = fz_dictgets(dict, "DescendantFonts");	error = pdf_resolve(&dfonts, xref);	if (error)		return fz_rethrow(error, "cannot find DescendantFonts");	dfont = fz_arrayget(dfonts, 0);	error = pdf_resolve(&dfont, xref);	if (error)	{		fz_dropobj(dfonts);		return fz_rethrow(error, "cannot find descendant font");	}	subtype = fz_dictgets(dfont, "Subtype");	encoding = fz_dictgets(dict, "Encoding");	tounicode = fz_dictgets(dict, "ToUnicode");	if (!strcmp(fz_toname(subtype), "CIDFontType0"))		error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode);	else if (!strcmp(fz_toname(subtype), "CIDFontType2"))		error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode);	else		error = fz_throw("syntaxerror: unknown cid font type");	fz_dropobj(dfont);	fz_dropobj(dfonts);	if (error)		return fz_rethrow(error, "cannot load descendant font");	return fz_okay;}/* * FontDescriptor */fz_error *pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection){	fz_error *error;	fz_obj *obj1, *obj2, *obj3, *obj;	fz_rect bbox;	char *fontname;	error = pdf_resolve(&desc, xref);	if (error)		return fz_rethrow(error, "cannot find font descriptor");	pdf_logfont("load fontdescriptor {\n");	obj = fz_dictgets(desc, "FontName");	if (error)		return fz_rethrow(error, "cannot resolve FontName");	fontname = fz_toname(obj);	pdf_logfont("fontname %s\n", fontname);	font->flags = fz_toint(fz_dictgets(desc, "Flags"));	font->italicangle = fz_toreal(fz_dictgets(desc, "ItalicAngle"));	font->ascent = fz_toreal(fz_dictgets(desc, "Ascent"));	font->descent = fz_toreal(fz_dictgets(desc, "Descent"));	font->capheight = fz_toreal(fz_dictgets(desc, "CapHeight"));	font->xheight = fz_toreal(fz_dictgets(desc, "XHeight"));	font->missingwidth = fz_toreal(fz_dictgets(desc, "MissingWidth"));	bbox = pdf_torect(fz_dictgets(desc, "FontBBox"));	pdf_logfont("bbox [%g %g %g %g]\n",			bbox.x0, bbox.y0,			bbox.x1, bbox.y1);	pdf_logfont("flags %d\n", font->flags);	obj1 = fz_dictgets(desc, "FontFile");	obj2 = fz_dictgets(desc, "FontFile2");	obj3 = fz_dictgets(desc, "FontFile3");	obj = obj1 ? obj1 : obj2 ? obj2 : obj3;	if (getenv("NOFONT"))		obj = nil;	if (fz_isindirect(obj))	{		error = pdf_loadembeddedfont(font, xref, obj);		if (error)			goto cleanup;	}	else	{		error = pdf_loadsystemfont(font, fontname, collection);		if (error)			goto cleanup;	}	fz_dropobj(desc);	pdf_logfont("}\n");	return fz_okay;cleanup:	fz_dropobj(desc);	return fz_rethrow(error, "cannot load font descriptor");}fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref){	fz_error *error;	char *subtype;	if ((*fontp = pdf_finditem(xref->store, PDF_KFONT, ref)))	{		fz_keepfont((fz_font*)*fontp);		return fz_okay;	}	subtype = fz_toname(fz_dictgets(dict, "Subtype"));	if (!strcmp(subtype, "Type0"))		error = loadtype0(fontp, xref, dict, ref);	else if (!strcmp(subtype, "Type1") || !strcmp(subtype, "MMType1"))		error = loadsimplefont(fontp, xref, dict, ref);	else if (!strcmp(subtype, "TrueType"))		error = loadsimplefont(fontp, xref, dict, ref);	else if (!strcmp(subtype, "Type3"))		error = pdf_loadtype3font(fontp, xref, dict, ref);	else		return fz_throw("cannot recognize font format %s", subtype);	if (error)		return fz_rethrow(error, "cannot load font");	error = pdf_storeitem(xref->store, PDF_KFONT, ref, *fontp);	if (error)		return fz_rethrow(error, "cannot store font resource");	return fz_okay;}

⌨️ 快捷键说明

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