shithub: pdffs

ref: b051539715907b60f5ccb8570f4665ad45b3fbaf
dir: /op.c/

View raw version
#include <u.h>
#include <libc.h>
#include "pdf.h"

enum {
	Evenodd = 1<<0,
	Nonstroking = 1<<1,
	Leading = 1<<2,
	Nextline = 1<<3,
	TwTc = 1<<4,
};

typedef struct Op Op;

struct Op {
	char *s;
	int (*f)(Op *op, Object *s);
	int argc;
	int flags;
};

static int
cobegin(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
coend(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gspush(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gspop(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsctm(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gswidth(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gscap(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsjoin(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsmiterlim(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsdash(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsintent(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsflatness(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
gsstate(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
pcmove(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
pcline(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
pccurve(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
pcsubpath(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
pcrect(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ppstroke(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ppstrokec(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ppfill(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ppfills(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ppfillcfs(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ppc(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
cpclip(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
cspace(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ccolour(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ccolour2(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
cgray(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
crgb(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
ccmyk(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
sshade(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
eoobject(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
iibegin(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
iidata(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
iiend(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tsspace(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tswspace(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tshscale(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tslead(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tsfontsz(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tsrendmode(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tsrise(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tobegin(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
toend(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tpmove(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tpmatrix(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
tpmove0(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
thshow(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
thshowarr(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t3width(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t3widthbb(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4add(Op *op, Object *s)
{
	USED(op, s);
/*
	double x;
	x = objat(s+1, Onum)->num.d + objat(s+0, Onum)->num.d;
	s = pop(s);
	s->num.d = x;
	s->num.i = x;
*/
	return 0;
}

static int
t4sub(Op *op, Object *s)
{
	USED(op, s);
/*
	double x;
	x = objat(s+1, Onum)->num.d - objat(s+0, Onum)->num.d;
	s = pop(s);
	s->num.d = x;
	s->num.i = x;
*/
	return 0;
}

static int
t4mul(Op *op, Object *s)
{
	USED(op, s);
/*
	double x;

	x = objat(s+1, Onum)->num.d * objat(s+0, Onum)->num.d;
	s = pop(s);
	s->num.d = x;
	s->num.i = x;
*/
	return 0;
}

static int
t4div(Op *op, Object *s)
{
	USED(op, s);
/*
	double x;

	x = objat(s+1, Onum)->num.d / objat(s+0, Onum)->num.d;
	s = pop(s);
	s->num.d = x;
	s->num.i = x;
*/
	return 0;
}

static int
t4idiv(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4mod(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4neg(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4abs(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4ceiling(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4floor(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4round(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4truncate(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4sqrt(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4sin(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4cos(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4atan(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4exp(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4ln(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4log(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4cvi(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4cvr(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4eq(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4ne(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4gt(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4ge(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4lt(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4le(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4and(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4or(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4xor(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4not(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4bitshift(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4true(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4false(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4if(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4ifelse(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4pop(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4exch(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4dup(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4copy(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4index(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static int
t4roll(Op *op, Object *s)
{
	USED(op, s);
	return 0;
}

static Op ops[] = {
	/* 7.8.2 Compatibility operators */
	{"BX", cobegin, 0,}, /* begin a compatilibity section */
	{"EX", coend, 0,},   /* end a compatilibity section */

	/* 8.4.4 Graphics state operators */
	{"q", gspush, 0,},   /* push the current graphics state (gs) on gs stack */
	{"Q", gspop, 0,},    /* pop ^ */
	{"cm", gsctm, 6,},     /* current transformation matrix (ctm) */
	{"w", gswidth, 1,},    /* line width */
	{"J", gscap, 1,},      /* line cap style */
	{"j", gsjoin, 1,},     /* line join style */
	{"M", gsmiterlim, 1,}, /* miter limit */
	{"d", gsdash, 2,},     /* line dash pattern */
	{"ri", gsintent, 1,},  /* colour rendering intent */
	{"i", gsflatness, 1,}, /* flatness tolerance */
	{"gs", gsstate, 1,},   /* graphics state parameters */

	/* 8.5.2 Path construction operators */
	{"m", pcmove, 2,},   /* move to coords */
	{"l", pcline, 2,},   /* straight line to coords */
	{"c", pccurve, 6,},  /* Bézier curve */
	{"v", pccurve, 4,},  /* Bézier curve */
	{"y", pccurve, 4,},  /* Bézier curve */
	{"h", pcsubpath, 0}, /* close subpath */
	{"re", pcrect, 4,},  /* rectangle */

	/* 8.5.3 Path painting operators */
	{"S", ppstroke, 0,},            /* stroke the path */
	{"s", ppstrokec, 0,},           /* close and stroke */
	{"f", ppfill, 0,},              /* fill */
	{"F", ppfill, 0,},              /* same damn thing, but DEPRECATED */
	{"f*", ppfill, 0, Evenodd,},    /* fill, even/odd rule */
	{"B", ppfills, 0,},             /* fill and stroke */
	{"B*", ppfills, 0, Evenodd,},   /* fill and stroke, even/odd rule */
	{"b", ppfillcfs, 0,},           /* close, fill and stroke */
	{"b*", ppfillcfs, 0, Evenodd,}, /* close, fill and stroke, even/odd rule */
	{"n", ppc, 0, 0},               /* end the path */

	/* 8.5.4 Clipping path operators */
	{"W", cpclip, 0,},           /* clip */
	{"W*", cpclip, 0, Evenodd,}, /* clip, even/odd rule */

	/* 8.6.8 Colour operators */
	{"CS", cspace, 1,},               /* colour space */
	{"cs", cspace, 1, Nonstroking,},  /* colour space, nonstroking */
	{"SC", ccolour, -1,},              /* colour */
	{"sc", ccolour, -1, Nonstroking,}, /* colour, nonstroking */
	{"SCN", ccolour2, -1,},            /* color (more spaces) */
	{"scn", ccolour2, -1,},            /* color (more spaces), nonstroking */
	{"G", cgray, 1,},                 /* gray */
	{"g", cgray, 1, Nonstroking,},    /* gray, nonstroking */
	{"RG", crgb, 3,},                 /* RGB */
	{"rg", crgb, 3, Nonstroking,},    /* RGB, nonstroking */
	{"K", ccmyk, 4,},                 /* CMYK */
	{"k", ccmyk, 4, Nonstroking,},    /* CMYK, nonstroking */

	/* 8.7.4.2 Shading operator */
	{"sh", sshade, 1,}, /* shading */

	/* 8.8 External objects */
	{"Do", eoobject, 1,}, /* paint XObject */

	/* 8.9.7 Inline images */
	{"BI", iibegin, 0,}, /* begin */
	{"ID", iidata, 0,},  /* data */
	{"EI", iiend, 0,},   /* end */

	/* 9.3.1 Text state parameters */
	{"Tc", tsspace, 1,},    /* spacing */
	{"Tw", tswspace, 1,},   /* word spacing */
	{"Tz", tshscale, 1,},   /* horizontal spacing */
	{"TL", tslead, 1,},     /* leading */
	{"Tf", tsfontsz, 1,},   /* font size */
	{"Tr", tsrendmode, 1,}, /* rendeing mode */
	{"Ts", tsrise, 1,},     /* rise */

	/* 9.4.1 Text objects */
	{"BT", tobegin, 0,}, /* begin */
	{"ET", toend, 0,},   /* end */

	/* 9.4.2 Text position operators */
	{"Td", tpmove, 2,},           /* move, next line */
	{"TD", tpmove, 2, Leading,},  /* move, next line, leading */
	{"Tm", tpmatrix, 6,},         /* (line) matrix */
	{"T*", tpmove0, 0, Leading,}, /* move, next line, leading */

	/* 9.4.3 Text showing operators */
	{"Tj", thshow, 1,},                /* show string */
	{"'", thshow, 1, Nextline,},       /* next line & show */
	{"\"", thshow, 3, Nextline|TwTc,}, /* next line, Tw, Tc & show */
	{"TJ", thshowarr, 1,},             /* show array */

	/* 9.6.4 Type 3 font operators */
	{"d0", t3width, 2,},   /* width info */
	{"d1", t3widthbb, 6,}, /* width & bounding box */

	/* 7.10.5.2 Operators and operands */
	/* B.2 Arithmetic operators */
	{"add", t4add, 2,},
	{"sub", t4sub, 2,},
	{"mul", t4mul, 2,},
	{"div", t4div, 2,},
	{"idiv", t4idiv, 2,},
	{"mod", t4mod, 2,},
	{"neg", t4neg, 1,},
	{"abs", t4abs, 1,},
	{"ceiling", t4ceiling, 1,},
	{"floor", t4floor, 1,},
	{"round", t4round, 1,},
	{"truncate", t4truncate, 1,},
	{"sqrt", t4sqrt, 1,},
	{"sin", t4sin, 1,},
	{"cos", t4cos, 1,},
	{"atan", t4atan, 2,},
	{"exp", t4exp, 2,},
	{"ln", t4ln, 1,},
	{"log", t4log, 1,},
	{"cvi", t4cvi, 1,},
	{"cvr", t4cvr, 1,},
	/* B.3 Relational, boolean, and bitwise operators */
	{"eq", t4eq, 2,},
	{"ne", t4ne, 2,},
	{"gt", t4gt, 2,},
	{"ge", t4ge, 2,},
	{"lt", t4lt, 2,},
	{"le", t4le, 2,},
	{"and", t4and, 2,},
	{"or", t4or, 2,},
	{"xor", t4xor, 2,},
	{"not", t4not, 1,},
	{"bitshift", t4bitshift, 2,},
	{"true", t4true, 0,},
	{"false", t4false, 0,},
	/* B.4 Conditional operators */
	{"if", t4if, 2,},
	{"ifelse", t4ifelse, 3,},
	/* B.5 Stack operators */
	{"pop", t4pop, 1,},
	{"exch", t4exch, 2,},
	{"dup", t4dup, 1,},
	{"copy", t4copy, -1,},
	{"index", t4index, -1,},
	{"roll", t4roll, -2,},

	/* terminator */
	{nil, nil, 0},
};

Op *
opfind(char *name)
{
	int i;
	Op *op;
	i = 0;
	op = &ops[0];
	while(op->s != nil){
		if(strcmp(op->s, name) == 0)
			return op;
		i += 1;
		op = &ops[i];
	}
	return nil;
}