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

📄 pdf_build.c

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "fitz.h"#include "mupdf.h"voidpdf_initgstate(pdf_gstate *gs){	gs->linewidth = 1.0;	gs->linecap = 0;	gs->linejoin = 0;	gs->miterlimit = 10;	gs->dashphase = 0;	gs->dashlen = 0;	memset(gs->dashlist, 0, sizeof(gs->dashlist));	gs->stroke.kind = PDF_MCOLOR;	gs->stroke.cs = fz_keepcolorspace(pdf_devicegray);	gs->stroke.v[0] = 0;	gs->stroke.indexed = nil;	gs->stroke.pattern = nil;	gs->stroke.shade = nil;	gs->stroke.alpha = 1.0;	gs->fill.kind = PDF_MCOLOR;	gs->fill.cs = fz_keepcolorspace(pdf_devicegray);	gs->fill.v[0] = 0;	gs->fill.indexed = nil;	gs->fill.pattern = nil;	gs->fill.shade = nil;	gs->fill.alpha = 1.0;	gs->blendmode = FZ_BNORMAL;	gs->charspace = 0;	gs->wordspace = 0;	gs->scale = 1;	gs->leading = 0;	gs->font = nil;	gs->size = -1;	gs->render = 0;	gs->rise = 0;	gs->head = nil;}fz_error *pdf_newovernode(fz_node **nodep, pdf_gstate *gs){    if (gs->blendmode == FZ_BNORMAL)	return fz_newovernode(nodep);    else	return fz_newblendnode(nodep, gs->blendmode, 0, 0);}fz_error *pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs){	pdf_gstate *gs = csi->gstate + csi->gtop;	fz_error *error;	pdf_material *mat;	error = pdf_flushtext(csi);	if (error)		return fz_rethrow(error, "cannot finish text node (state change)");	mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;	fz_dropcolorspace(mat->cs);	mat->kind = PDF_MCOLOR;	mat->cs = fz_keepcolorspace(cs);	mat->v[0] = 0;	/* FIXME: default color */	mat->v[1] = 0;	/* FIXME: default color */	mat->v[2] = 0;	/* FIXME: default color */	mat->v[3] = 1;	/* FIXME: default color */	if (!strcmp(cs->name, "Indexed"))	{		mat->kind = PDF_MINDEXED;		mat->indexed = (pdf_indexed*)cs;		mat->cs = mat->indexed->base;	}	if (!strcmp(cs->name, "Lab"))		mat->kind = PDF_MLAB;	return fz_okay;}fz_error *pdf_setcolor(pdf_csi *csi, int what, float *v){	pdf_gstate *gs = csi->gstate + csi->gtop;	fz_error *error;	pdf_indexed *ind;	pdf_material *mat;	int i, k;	error = pdf_flushtext(csi);	if (error)		return fz_rethrow(error, "cannot finish text node (state change)");	mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;	switch (mat->kind)	{	case PDF_MPATTERN:		if (!strcmp(mat->cs->name, "Lab"))			goto Llab;		if (!strcmp(mat->cs->name, "Indexed"))			goto Lindexed;		/* fall through */	case PDF_MCOLOR:		for (i = 0; i < mat->cs->n; i++)			mat->v[i] = v[i];		break;	case PDF_MLAB:Llab:		mat->v[0] = v[0] / 100.0;		mat->v[1] = (v[1] + 100) / 200.0;		mat->v[2] = (v[2] + 100) / 200.0;		break;	case PDF_MINDEXED:Lindexed:		ind = mat->indexed;		i = CLAMP(v[0], 0, ind->high);		for (k = 0; k < ind->base->n; k++)			mat->v[k] = ind->lookup[ind->base->n * i + k] / 255.0;		break;	default:		return fz_throw("color incompatible with material");	}	return fz_okay;}fz_error *pdf_setpattern(pdf_csi *csi, int what, pdf_pattern *pat, float *v){	pdf_gstate *gs = csi->gstate + csi->gtop;	fz_error *error;	pdf_material *mat;	error = pdf_flushtext(csi);	if (error)		return fz_rethrow(error, "cannot finish text node (state change)");	mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;	if (mat->pattern)		pdf_droppattern(mat->pattern);	mat->kind = PDF_MPATTERN;	if (pat)		mat->pattern = pdf_keeppattern(pat);	else		mat->pattern = nil;	if (v)	{		error = pdf_setcolor(csi, what, v);		if (error)			return fz_rethrow(error, "cannot set color");	}	return fz_okay;}fz_error *pdf_setshade(pdf_csi *csi, int what, fz_shade *shade){	pdf_gstate *gs = csi->gstate + csi->gtop;	fz_error *error;	pdf_material *mat;	error = pdf_flushtext(csi);	if (error)		return fz_rethrow(error, "cannot finish text node (state change)");	mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;	if (mat->shade)		fz_dropshade(mat->shade);	mat->kind = PDF_MSHADE;	mat->shade = fz_keepshade(shade);	return fz_okay;}fz_error *pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path){	fz_error *error;	fz_stroke stroke;	fz_dash *dash;	stroke.linecap = gs->linecap;	stroke.linejoin = gs->linejoin;	stroke.linewidth = gs->linewidth;	stroke.miterlimit = gs->miterlimit;	if (gs->dashlen)	{		error = fz_newdash(&dash, gs->dashphase, gs->dashlen, gs->dashlist);		if (error)			return fz_rethrow(error, "cannot create dash pattern");	}	else		dash = nil;	error = fz_endpath(path, FZ_STROKE, &stroke, dash);	if (error)	{		fz_dropdash(dash);		return fz_rethrow(error, "cannot finish path node");	}	return fz_okay;}fz_error *pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int eofill){	fz_error *error;	error = fz_endpath(path, eofill ? FZ_EOFILL : FZ_FILL, nil, nil);	if (error)		return fz_rethrow(error, "cannot finish path node");	return fz_okay;}static fz_error *addcolorshape(pdf_gstate *gs, fz_node *shape, float alpha, fz_colorspace *cs, float *v){	fz_error *error;	fz_node *mask;	fz_node *solid;	error = fz_newmasknode(&mask);	if (error)		return fz_rethrow(error, "cannot create mask node");	error = fz_newsolidnode(&solid, alpha, cs, cs->n, v);	if (error)	{		fz_dropnode(mask);		return fz_rethrow(error, "cannot create color node");	}	fz_insertnodelast(mask, shape);	fz_insertnodelast(mask, solid);	fz_insertnodelast(gs->head, mask);	return fz_okay;}static fz_error *addinvisibleshape(pdf_gstate *gs, fz_node *shape){	fz_error *error;	fz_node *mask;	fz_pathnode *path;	error = fz_newmasknode(&mask);	if (error)		return fz_rethrow(error, "cannot create mask node");	error = fz_newpathnode(&path);	if (error)	{		fz_dropnode(mask);		return fz_rethrow(error, "cannot create path node");	}	error = fz_endpath(path, FZ_FILL, nil, nil);	if (error)	{		fz_dropnode(mask);		fz_dropnode((fz_node*)path);		return fz_rethrow(error, "cannot finish path node");	}	fz_insertnodelast(mask, (fz_node*)path);	fz_insertnodelast(mask, shape);	fz_insertnodelast(gs->head, mask);	return fz_okay;}static fz_matrix getmatrix(fz_node *node){	if (node->parent)	{		fz_matrix ptm = getmatrix(node->parent);		if (fz_istransformnode(node))			return fz_concat(((fz_transformnode*)node)->m, ptm);		return ptm;	}	if (fz_istransformnode(node))		return ((fz_transformnode*)node)->m;	return fz_identity();}static fz_error *addpatternshape(pdf_gstate *gs, fz_node *shape,		pdf_pattern *pat, fz_colorspace *cs, float *v){	fz_error *error;	fz_node *xform;	fz_node *over;	fz_node *mask;	fz_node *link;	fz_matrix ctm;	fz_matrix inv;	fz_matrix ptm;	fz_rect bbox;	int x, y, x0, y0, x1, y1;	/* patterns are painted in user space */	ctm = getmatrix(gs->head);	inv = fz_invertmatrix(ctm);	error = fz_newmasknode(&mask);	if (error)		return fz_rethrow(error, "cannot create mask node");	ptm = fz_concat(pat->matrix, fz_invertmatrix(ctm));	error = fz_newtransformnode(&xform, ptm);	if (error)	{		fz_dropnode(mask);		return fz_rethrow(error, "cannot create transform node");	}	error = pdf_newovernode(&over, gs);	if (error)	{		fz_dropnode(xform);		fz_dropnode(mask);		return fz_rethrow(error, "cannot create over node");	}	fz_insertnodelast(mask, shape);	fz_insertnodelast(mask, xform);	fz_insertnodelast(xform, over);	xform = nil;	/* over, xform, mask are now owned by the tree */	/* get bbox of shape in pattern space for stamping */	ptm = fz_concat(ctm, fz_invertmatrix(pat->matrix));	bbox = fz_boundnode(shape, ptm);	/* expand bbox by pattern bbox */	bbox.x0 += pat->bbox.x0;	bbox.y0 += pat->bbox.y0;	bbox.x1 += pat->bbox.x1;	bbox.y1 += pat->bbox.y1;	x0 = fz_floor(bbox.x0 / pat->xstep);	y0 = fz_floor(bbox.y0 / pat->ystep);	x1 = fz_ceil(bbox.x1 / pat->xstep);	y1 = fz_ceil(bbox.y1 / pat->ystep);	for (y = y0; y <= y1; y++)	{		for (x = x0; x <= x1; x++)		{			ptm = fz_translate(x * pat->xstep, y * pat->ystep);			error = fz_newtransformnode(&xform, ptm);			if (error)				return fz_rethrow(error, "cannot create transform node for stamp");			error = fz_newlinknode(&link, pat->tree);			if (error)			{				fz_dropnode(xform);				return fz_rethrow(error, "cannot create link node for stamp");			}			fz_insertnodelast(xform, link);			fz_insertnodelast(over, xform);		}	}	if (pat->ismask)	{		error = addcolorshape(gs, mask, 1.0, cs, v);		if (error)			return fz_rethrow(error, "cannot add colored shape");		return fz_okay;	}	fz_insertnodelast(gs->head, mask);	return fz_okay;}fz_error *pdf_addshade(pdf_gstate *gs, fz_shade *shade){	fz_error *error;	fz_node *node;	error = fz_newshadenode(&node, shade);	if (error)		return fz_rethrow(error, "cannot create shade node");	fz_insertnodelast(gs->head, node);	return fz_okay;}static fz_error *addshadeshape(pdf_gstate *gs, fz_node *shape, fz_shade *shade){	fz_error *error;	fz_node *mask;	fz_node *color;	fz_node *xform;	fz_node *over;	fz_node *bgnd;	fz_matrix ctm;	fz_matrix inv;	ctm = getmatrix(gs->head);	inv = fz_invertmatrix(ctm);	error = fz_newtransformnode(&xform, inv);	if (error)		return fz_rethrow(error, "cannot create transform node");	error = fz_newmasknode(&mask);	if (error)	{		fz_dropnode(xform);		return fz_rethrow(error, "cannot create mask node");	}	error = fz_newshadenode(&color, shade);	if (error)	{		fz_dropnode(mask);		fz_dropnode(xform);		return fz_rethrow(error, "cannot create shade node");	}	if (shade->usebackground)	{		error = pdf_newovernode(&over, gs);		if (error)		{			fz_dropnode(color);			fz_dropnode(mask);			fz_dropnode(xform);			return fz_rethrow(error, "cannot create over node for background color");		}		error = fz_newsolidnode(&bgnd, 1.0f, shade->cs, shade->cs->n, shade->background);		if (error)		{			fz_dropnode(over);			fz_dropnode(color);			fz_dropnode(mask);			fz_dropnode(xform);			return fz_rethrow(error, "cannot create solid node for background color");;		}		fz_insertnodelast(mask, shape);		fz_insertnodelast(over, bgnd);		fz_insertnodelast(over, color);		fz_insertnodelast(xform, over);		fz_insertnodelast(mask, xform);		fz_insertnodelast(gs->head, mask);	}	else	{		fz_insertnodelast(mask, shape);		fz_insertnodelast(xform, color);		fz_insertnodelast(mask, xform);		fz_insertnodelast(gs->head, mask);	}	return fz_okay;}fz_error *pdf_addfillshape(pdf_gstate *gs, fz_node *shape){	fz_error *error;	switch (gs->fill.kind)

⌨️ 快捷键说明

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