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

📄 pdf_type3.c

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 C
字号:
#include "fitz.h"#include "mupdf.h"/* TODO: we leak the pixmap buffer. not good. we should render into the glyph cache directly or keep it in the font struct.. */#define GCMEM (4 * 1024)extern pdf_font *pdf_newfont(char *name);static voidt3dropfont(fz_font *font){	int i;	pdf_font *pfont = (pdf_font*)font;	if (pfont->encoding)		pdf_dropcmap(pfont->encoding);	for (i = 0; i < 256; i++)		if (pfont->charprocs[i])			fz_droptree(pfont->charprocs[i]);}static fz_error *t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm){	pdf_font *font = (pdf_font*)fzfont;	fz_error *error;	fz_renderer *gc;	fz_tree *tree;	fz_pixmap *pixmap;	fz_matrix ctm;	fz_irect bbox;	if (cid < 0 || cid > 255)		return fz_throw("assert: glyph out of range");	tree = font->charprocs[cid];	if (!tree)	{		glyph->w = 0;		glyph->h = 0;		return fz_okay;	}	ctm = fz_concat(font->matrix, trm);	bbox = fz_roundrect(fz_boundtree(tree, ctm));	error = fz_newrenderer(&gc, pdf_devicegray, 1, GCMEM);	if (error)		return fz_rethrow(error, "cannot create renderer");	error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);	fz_droprenderer(gc);	if (error)		return fz_rethrow(error, "cannot render glyph");	assert(pixmap->n == 1);	glyph->x = pixmap->x;	glyph->y = pixmap->y;	glyph->w = pixmap->w;	glyph->h = pixmap->h;	glyph->samples = pixmap->samples;	return fz_okay;}static fz_error *loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref){	fz_error *error;	pdf_csi *csi;	fz_stream *stm;	error = pdf_newcsi(&csi, 1);	if (error)		return fz_rethrow(error, "cannot create interpreter");	error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref));	if (error)	{		pdf_dropcsi(csi);		return fz_rethrow(error, "cannot open glyph content stream");	}	error = pdf_runcsi(csi, xref, rdb, stm);	if (error)	{		fz_dropstream(stm);		pdf_dropcsi(csi);		return fz_rethrow(error, "cannot interpret glyph content stream");	}	*treep = csi->tree;	csi->tree = nil;	fz_dropstream(stm);	pdf_dropcsi(csi);	return fz_okay;}fz_error *pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref){	fz_error *error;	char buf[256];	char *estrings[256];	pdf_font *font;	fz_obj *encoding;	fz_obj *widths;	fz_obj *resources;	fz_obj *charprocs;	fz_obj *obj;	int first, last;	int i, k, n;	fz_rect bbox;	obj = fz_dictgets(dict, "Name");	if (obj)		strlcpy(buf, fz_toname(obj), sizeof buf);	else		sprintf(buf, "Unnamed-T3");	font = pdf_newfont(buf);	if (!font)		return fz_throw("outofmem: font struct");	pdf_logfont("load type3 font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), font);	pdf_logfont("name %s\n", buf);	font->super.render = t3render;	font->super.drop = (void(*)(fz_font*)) t3dropfont;	obj = fz_dictgets(dict, "FontMatrix");	font->matrix = pdf_tomatrix(obj);	pdf_logfont("matrix [%g %g %g %g %g %g]\n",			font->matrix.a, font->matrix.b,			font->matrix.c, font->matrix.d,			font->matrix.e, font->matrix.f);	obj = fz_dictgets(dict, "FontBBox");	bbox = pdf_torect(obj);	pdf_logfont("bbox [%g %g %g %g]\n",			bbox.x0, bbox.y0,			bbox.x1, bbox.y1);	bbox = fz_transformaabb(font->matrix, bbox);	bbox.x0 = fz_floor(bbox.x0 * 1000);	bbox.y0 = fz_floor(bbox.y0 * 1000);	bbox.x1 = fz_ceil(bbox.x1 * 1000);	bbox.y1 = fz_ceil(bbox.y1 * 1000);	fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);	/*	 * Encoding	 */	for (i = 0; i < 256; i++)		estrings[i] = nil;	encoding = fz_dictgets(dict, "Encoding");	if (!encoding) {		error = fz_throw("syntaxerror: Type3 font missing Encoding");		goto cleanup;	}	error = pdf_resolve(&encoding, xref);	if (error)		goto cleanup;	if (fz_isname(obj))		pdf_loadencoding(estrings, fz_toname(encoding));	if (fz_isdict(encoding))	{		fz_obj *base, *diff, *item;		base = fz_dictgets(encoding, "BaseEncoding");		if (fz_isname(base))			pdf_loadencoding(estrings, fz_toname(base));		diff = fz_dictgets(encoding, "Differences");		if (fz_isarray(diff))		{			n = fz_arraylen(diff);			k = 0;			for (i = 0; i < n; i++)			{				item = fz_arrayget(diff, i);				if (fz_isint(item))					k = fz_toint(item);				if (fz_isname(item))					estrings[k++] = fz_toname(item);				if (k < 0) k = 0;				if (k > 255) k = 255;			}		}	}	fz_dropobj(encoding);	error = pdf_newidentitycmap(&font->encoding, 0, 1);	if (error)		goto cleanup;	error = pdf_loadtounicode(font, xref,			estrings, nil, fz_dictgets(dict, "ToUnicode"));	if (error)		goto cleanup;	/*	 * Widths	 */	fz_setdefaulthmtx((fz_font*)font, 0);	first = fz_toint(fz_dictgets(dict, "FirstChar"));	last = fz_toint(fz_dictgets(dict, "LastChar"));	widths = fz_dictgets(dict, "Widths");	if (!widths) {		error = fz_throw("syntaxerror: Type3 font missing Widths");		goto cleanup;	}	error = pdf_resolve(&widths, xref);	if (error)		goto cleanup;	for (i = first; i <= last; i++)	{		float w = fz_toreal(fz_arrayget(widths, i - first));		w = font->matrix.a * w * 1000.0;		error = fz_addhmtx((fz_font*)font, i, i, w);		if (error) {			fz_dropobj(widths);			goto cleanup;		}	}	fz_dropobj(widths);	error = fz_endhmtx((fz_font*)font);	if (error)		goto cleanup;	/*	 * Resources	 */	resources = nil;	obj = fz_dictgets(dict, "Resources");	if (obj)	{		error = pdf_resolve(&obj, xref);		if (error)			goto cleanup;		error = pdf_loadresources(&resources, xref, obj);		fz_dropobj(obj);		if (error)			goto cleanup;	}	else		pdf_logfont("no resource dict!\n");	/*	 * CharProcs	 */	charprocs = fz_dictgets(dict, "CharProcs");	if (!charprocs)	{		error = fz_throw("syntaxerror: Type3 font missing CharProcs");		goto cleanup2;	}	error = pdf_resolve(&charprocs, xref);	if (error)		goto cleanup2;	for (i = 0; i < 256; i++)	{		if (estrings[i])		{			obj = fz_dictgets(charprocs, estrings[i]);			if (obj)			{				pdf_logfont("load charproc %s {\n", estrings[i]);				error = loadcharproc(&font->charprocs[i], xref, resources, obj);				if (error)					goto cleanup2;				error = fz_optimizetree(font->charprocs[i]);				if (error)					goto cleanup2;				pdf_logfont("}\n");			}		}	}	fz_dropobj(charprocs);	if (resources)		fz_dropobj(resources);	pdf_logfont("}\n");	*fontp = font;	return fz_okay;cleanup2:	if (resources)		fz_dropobj(resources);cleanup:	fz_dropfont((fz_font*)font);	return fz_rethrow(error, "cannot load type3 font");}

⌨️ 快捷键说明

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