Sigrid Solveig Haflínudóttirthis is not Go5949d533 years agoHistory
1564 lines · 29.3 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <memdraw.h>#include "pdf.h" enum {	Evenodd = 1<<0,	Nonstroking = 1<<1,	Leading = 1<<2,	Nextline = 1<<3,	TwTc = 1<<4,}; typedef struct Op Op; static voidmatidentity(double *arr){	double src[6] = {					1, 0,					0, 1,					0, 0	};	memcpy(arr, src, sizeof(double) * 6);} static voidmatmult(double *m1, double *m2, double *out){	double result[6];	result[0] = m1[0] * m2[0] + m1[1] * m2[2];	result[1] = m1[0] * m2[1] + m1[1] * m2[3];	result[2] = m1[2] * m2[0] + m1[3] * m2[2];	result[3] = m1[2] * m2[1] + m1[3] * m2[3];	result[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];	result[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];	memcpy(out, result, sizeof(double) * 6);} static voidmattrans(double *m1, double x, double y, double *out){	double mult[6] = {		1, 0,		0, 1,		x, y,	};	matmult(mult, m1, out);} static voidmatscale(double *m1, double x, double y, double *out){	double mult[6] = {		x, 0,		0, y,		0, 0,	};	matmult(mult, m1, out);} struct Op {	char *s;	int (*f)(Op *op, Page *p);	int argc;	int flags;}; static intflagless(Op *op){	if(op->flags != 0){		werrstr("op %q: expected no flags", op->s);		return -1;	}	return 0;} static intcobegin(Op *op, Page *p){	USED(op, p);	return -1;} static intcoend(Op *op, Page *p){	USED(op, p);	return -1;} static intgspush(Op *op, Page *p){	GS *r; 	USED(op);	if((r = realloc(p->GS, sizeof(GS) * (p->nGS + 1))) == nil)		return -1;	p->GS = r;	p->nGS++;	p->GSactive = &p->GS[p->nGS - 1];	*(p->GSactive) = p->GS[p->nGS - 2];	if(p->GSactive->Font.widths != nil){		p->GSactive->Font.widths = malloc(sizeof(int) * (p->GSactive->Font.last - p->GSactive->Font.first + 1));		if(p->GSactive->Font.widths == nil){			werrstr("gspush: out of memory allocating space for glyph widths");			return -1;		}		memcpy(p->GSactive->Font.widths, p->GS[p->nGS - 2].Font.widths, sizeof(int) * (p->GSactive->Font.last - p->GSactive->Font.first + 1));	}	return 0;} static intgspop(Op *op, Page *p){	USED(op);	free(p->GSactive->Font.widths);	GS *r = realloc(p->GS, sizeof(GS) * (p->nGS - 1));	if(r == nil)		return -1;	p->GS = r;	p->nGS--;	p->GSactive = &p->GS[p->nGS - 1];	return 0;} /* six parameters give the inputs a,b,c,d,e,f for the matrix	[a b 0]	[c d 0]	[e f 1] That matrix should be premultiplied with the current matrix newCTM = input x oldCTM (8.3.4) */static intgsctm(Op *op, Page *p){	double input[6];	int i; 	for(i = 0; i < 6; i++)		input[i] = arrayget(p->stack, i)->num.d;	matmult(input, p->GSactive->CTM, p->GSactive->CTM);	return flagless(op);} static intgswidth(Op *op, Page *p){	p->GSactive->LW = arrayget(p->stack, 0)->num.d;	if(p->GSactive->LW < 0){		werrstr("gswidth: invalid line width: %f", p->GSactive->LW);		return -1;	}	return flagless(op);} static intgscap(Op *op, Page *p){	p->GSactive->LC = arrayget(p->stack, 0)->num.d;	if(p->GSactive->LC > CapEND){		werrstr("gscap: invalid line cap: %d", p->GSactive->LC);		return -1;	}	return flagless(op);} static intgsjoin(Op *op, Page *p){	p->GSactive->LJ = arrayget(p->stack, 0)->num.d;	if(p->GSactive->LJ > JoinEND){		werrstr("gsjoin: invalid line join: %d", p->GSactive->LJ);		return -1;	}	return flagless(op);} static intgsmiterlim(Op *op, Page *p){	p->GSactive->ML = arrayget(p->stack, 0)->num.d;	if(p->GSactive->ML < 0){		werrstr("gsmiterlim: invalidmiter limit: %f", p->GSactive->ML);		return -1;	}	return flagless(op);} static intgsdash(Op *op, Page *p){	USED(op, p);	return -1;} static intgsintent(Op *op, Page *p){	USED(op, p);	return -1;} static intgsflatness(Op *op, Page *p){	p->GSactive->FL = arrayget(p->stack, 0)->num.d;	return flagless(op);} static intgsstate(Op *op, Page *p){	char *name = arrayget(p->stack, 0)->name;	Object *gs, *o;	if((gs = dictget(dictget(dictget(p->obj, "Resources"), "ExtGState"), name)) == &null){		werrstr("extgstate dictionary not found: %s", name);		goto err;	}	if((o = dictget(gs, "Type")) != &null && strcmp(o->name, "ExtGState") != 0){		werrstr("invalid type on ExtGState object: %s", o->name);		goto err;	}	if((o = dictget(gs, "LW")) != &null){		if(o->type != Onum){			werrstr("line width is not a number");			goto err;		}		p->GSactive->LW = o->num.d;	}	if((o = dictget(gs, "LC")) != &null){		if(o->type != Onum){			werrstr("line cap is not a number");			goto err;		}		p->GSactive->LC = o->num.i;	}	if((o = dictget(gs, "LJ")) != &null){		if(o->type != Onum){			werrstr("line join is not a number");			goto err;		}		p->GSactive->LJ = o->num.i;	}	if((o = dictget(gs, "ML")) != &null){		if(o->type != Onum){			werrstr("miter limit is not a number");			goto err;		}		p->GSactive->ML = o->num.d;	}	return flagless(op);err:	werrstr("gsstate: %r");	return -1;} static intpcmove(Op *op, Page *p){	USED(op, p);	return -1;} static intpcline(Op *op, Page *p){	USED(op, p);	return -1;} static intpccurve(Op *op, Page *p){	USED(op, p);	return -1;} static intpcsubpath(Op *op, Page *p){	USED(op, p);	return -1;} static intpcrect(Op *op, Page *p){	USED(op, p);	return -1;} static intppstroke(Op *op, Page *p){	USED(op, p);	return -1;} static intppstrokec(Op *op, Page *p){	USED(op, p);	return -1;} static intppfill(Op *op, Page *p){	USED(op, p);	return -1;} static intppfills(Op *op, Page *p){	USED(op, p);	return -1;} static intppfillcfs(Op *op, Page *p){	USED(op, p);	return -1;} static intppc(Op *op, Page *p){	USED(op, p);	return -1;} static intcpclip(Op *op, Page *p){	USED(op, p);	return -1;} static char *colorspacedevices[] = {"DeviceGray", "DeviceRGB", "DeviceCMYK"};static ColorSpace colorspacechans[] = {	[1] = DeviceGray,	[3] = DeviceRGB,	[4] = DeviceCMYK,}; static inticcbasedcspace(Object *icc, ColorSpace *c){	Object *o; 	*c = colorspacechans[dictint(icc, "N")];	if((o = dictget(icc, "Alternate")) != &null){		if(*c > 2 || strcmp(colorspacedevices[*c], o->name) != 0){			werrstr("iccbasedcspace: TODO: handle non-device alternate %q", o->name);			return -1;		}	}	return 0;} static intcspace(Op *op, Page *p){	ColorSpace *c = (op->flags & Nonstroking) ? &p->GSactive->NSCS : &p->GSactive->SCS;	u32int *color = (op->flags & Nonstroking) ? &p->GSactive->NSC : &p->GSactive->SC;	char *s = arrayget(p->stack, 0)->name;	Object *o;	int i; 	for(i = 0; i < nelem(colorspacedevices); i++){		if(strcmp(s, colorspacedevices[i]) == 0){			*c = i;			*color = i == 2 ? 0xFF : 0;			return 0;		}	}	if((o = dictget(dictget(p->obj, "Resources"), "ColorSpace")) == &null		|| (o = dictget(o, s)) == &null){		werrstr("colorspace not found: %q", s);		return -1;	}	if(strcmp(arrayget(o, 0)->name, "ICCBased") == 0){		/* Don't support ICC; fall back to Alternate or default */		o = arrayget(o, 1);		if(!iccbasedcspace(o, c))			return -1;		*color = *c == 2 ? 0xFF : 0;		return 0;	}	werrstr("cspace: TODO: color space %q", arrayget(o, 0)->name);	return -1;} static intccolour(Op *op, Page *p){	ColorSpace c = op->flags & Nonstroking ? p->GSactive->NSCS : p->GSactive->SCS;	u32int *color = op->flags & Nonstroking ? &p->GSactive->NSC : &p->GSactive->SC; 	if(c == DeviceRGB){		*color = ((u8int)(255 * arrayget(p->stack, 0)->num.d)) << 24 | ((u8int)(255 * arrayget(p->stack, 1)->num.d)) << 16 | ((u8int)(255 * arrayget(p->stack, 2)->num.d)) << 8 | 0xff;		return 0;	}	return -1;} static intccolour2(Op *op, Page *p){	ColorSpace c = op->flags & Nonstroking ? p->GSactive->NSCS : p->GSactive->SCS;	if(c < 3)		return ccolour(op, p);	return -1;} static intcgray(Op *op, Page *p){	int value = 255 * arrayget(p->stack, 0)->num.d;	u32int *color;	int i; 	if(op->flags & Nonstroking){		color = &p->GSactive->NSC;		p->GSactive->NSCS = DeviceGray;	}else{		color = &p->GSactive->SC;		p->GSactive->SCS = DeviceGray;	}	*color = 0;	for(i = 0; i < 3; i++)		*color = (*color | value) << 8;	*color |= 255;	return 0;} static intcrgb(Op *op, Page *p){	USED(op, p);	return -1;} static intccmyk(Op *op, Page *p){	USED(op, p);	return -1;} static intsshade(Op *op, Page *p){	USED(op, p);	return -1;} static inteoobject(Op *op, Page *p){	USED(op, p);	return -1;} static intiibegin(Op *op, Page *p){	USED(op, p);	return -1;} static intiidata(Op *op, Page *p){	USED(op, p);	return -1;} static intiiend(Op *op, Page *p){	USED(op, p);	return -1;} static inttsspace(Op *op, Page *p){	USED(op);	p->TS.Tc = arrayget(p->stack, 0)->num.d;	return 0;}

Lines 1–500 of 1564.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t